diff --git a/examples/nested-routes/app.js b/examples/nested-routes/app.js index 6e8ba8689..9f35e3064 100644 --- a/examples/nested-routes/app.js +++ b/examples/nested-routes/app.js @@ -28,6 +28,14 @@ const Qux = { ` } +const Quy = { + template: ` +
+

quy

+
{{ JSON.stringify(Object.keys($route.params)) }}
+
+ ` +} const Quux = { template: '
quux
' } const router = new VueRouter({ @@ -57,7 +65,9 @@ const router = new VueRouter({ path: 'qux/:quxId', component: Qux, children: [{ path: 'quux', name: 'quux', component: Quux }] - } + }, + + { path: 'quy/:quyId', component: Quy } ] } ] @@ -74,6 +84,7 @@ new Vue({
  • /parent/bar
  • /baz
  • /parent/qux
  • +
  • /parent/quy
  • diff --git a/src/create-matcher.js b/src/create-matcher.js index 1850c5284..748f451e8 100644 --- a/src/create-matcher.js +++ b/src/create-matcher.js @@ -14,6 +14,10 @@ const regexpCache: { } } = Object.create(null) +const regexpParamsCache: { + [key: string]: Array +} = Object.create(null) + const regexpCompileCache: { [key: string]: Function } = Object.create(null) @@ -31,6 +35,7 @@ export function createMatcher (routes: Array): Matcher { if (name) { const record = nameMap[name] + const paramNames = getParams(record.path) if (typeof location.params !== 'object') { location.params = {} @@ -38,7 +43,7 @@ export function createMatcher (routes: Array): Matcher { if (currentRoute && typeof currentRoute.params === 'object') { for (const key in currentRoute.params) { - if (!(key in location.params)) { + if (!(key in location.params) && paramNames.indexOf(key) > -1) { location.params[key] = currentRoute.params[key] } } @@ -150,13 +155,10 @@ export function createMatcher (routes: Array): Matcher { return match } -function matchRoute ( - path: string, - params: Object, - pathname: string -): boolean { - let keys, regexp +function getRouteRegex (path: string): Object { const hit = regexpCache[path] + let keys, regexp + if (hit) { keys = hit.keys regexp = hit.regexp @@ -165,6 +167,16 @@ function matchRoute ( regexp = Regexp(path, keys) regexpCache[path] = { keys, regexp } } + + return { keys, regexp } +} + +function matchRoute ( + path: string, + params: Object, + pathname: string +): boolean { + const { regexp, keys } = getRouteRegex(path) const m = pathname.match(regexp) if (!m) { @@ -198,6 +210,11 @@ function fillParams ( } } +function getParams (path: string): Array { + return regexpParamsCache[path] || + (regexpParamsCache[path] = getRouteRegex(path).keys.map(key => key.name)) +} + function resolveRecordPath (path: string, record: RouteRecord): string { return resolvePath(path, record.parent ? record.parent.path : '/', true) } diff --git a/test/e2e/specs/nested-routes.js b/test/e2e/specs/nested-routes.js index 41aecaa2d..172ded37e 100644 --- a/test/e2e/specs/nested-routes.js +++ b/test/e2e/specs/nested-routes.js @@ -3,7 +3,7 @@ module.exports = { browser .url('http://localhost:8080/nested-routes/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 5) + .assert.count('li a', 6) .assert.urlEquals('http://localhost:8080/nested-routes/parent') .assert.containsText('.view', 'Parent') .assert.containsText('.view', 'default') @@ -34,6 +34,17 @@ module.exports = { .assert.containsText('.view', 'qux') .assert.containsText('.view', 'quux') + .click('li:nth-child(6) a') + .assert.urlEquals('http://localhost:8080/nested-routes/parent/quy/123') + .assert.containsText('.view', 'Parent') + .assert.containsText('.view', 'quy') + .assert.evaluate(function () { + var params = JSON.parse(document.querySelector('pre').textContent) + return ( + JSON.stringify(params) === JSON.stringify(['quyId']) + ) + }, null, '/') + // check initial visit .url('http://localhost:8080/nested-routes/parent/foo') .waitForElementVisible('#app', 1000)