Skip to content

Commit ca80c44

Browse files
committed
feat: addRoute as nested route
Close #1156
1 parent d80bcdf commit ca80c44

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

src/create-matcher.js

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { decode } from './util/query'
1212
export type Matcher = {
1313
match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
1414
addRoutes: (routes: Array<RouteConfig>) => void;
15+
addRoute: (parentNameOrRoute: string | RouteConfig, route?: RouteConfig) => void;
1516
};
1617

1718
export function createMatcher (
@@ -24,6 +25,12 @@ export function createMatcher (
2425
createRouteMap(routes, pathList, pathMap, nameMap)
2526
}
2627

28+
function addRoute (parentOrRoute, route) {
29+
const parent = (typeof parentOrRoute !== 'object') ? nameMap[parentOrRoute] : undefined
30+
// $flow-disable-line
31+
createRouteMap([route || parentOrRoute], pathList, pathMap, nameMap, parent)
32+
}
33+
2734
function match (
2835
raw: RawLocation,
2936
currentRoute?: Route,
@@ -167,6 +174,7 @@ export function createMatcher (
167174

168175
return {
169176
match,
177+
addRoute,
170178
addRoutes
171179
}
172180
}

src/create-route-map.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export function createRouteMap (
88
routes: Array<RouteConfig>,
99
oldPathList?: Array<string>,
1010
oldPathMap?: Dictionary<RouteRecord>,
11-
oldNameMap?: Dictionary<RouteRecord>
11+
oldNameMap?: Dictionary<RouteRecord>,
12+
parentRoute?: RouteRecord
1213
): {
1314
pathList: Array<string>,
1415
pathMap: Dictionary<RouteRecord>,
@@ -22,7 +23,7 @@ export function createRouteMap (
2223
const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null)
2324

2425
routes.forEach(route => {
25-
addRouteRecord(pathList, pathMap, nameMap, route)
26+
addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)
2627
})
2728

2829
// ensure wildcard routes are always at the end

src/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,13 @@ export default class VueRouter {
244244
}
245245
}
246246

247+
addRoute (parentOrRoute: string | RouteConfig, route?: RouteConfig) {
248+
this.matcher.addRoute(parentOrRoute, route)
249+
if (this.history.current !== START) {
250+
this.history.transitionTo(this.history.getCurrentLocation())
251+
}
252+
}
253+
247254
addRoutes (routes: Array<RouteConfig>) {
248255
this.matcher.addRoutes(routes)
249256
if (this.history.current !== START) {

test/unit/specs/create-matcher.spec.js

+32
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,38 @@ describe('Creating Matcher', function () {
2222
process.env.NODE_ENV = 'production'
2323
})
2424

25+
it('can add nested routes', function () {
26+
const component = { name: 'fake' }
27+
const matcher = createMatcher([
28+
{
29+
path: '/p',
30+
name: 'parent',
31+
children: [
32+
{ path: 'a', name: 'a', component },
33+
{
34+
path: 'c',
35+
name: 'child',
36+
component,
37+
children: [{ path: 'n', name: 'nested', component }]
38+
}
39+
]
40+
},
41+
{
42+
// easier to debug tests
43+
path: '*', name: 'not-found', component
44+
}
45+
])
46+
47+
matcher.addRoute({ path: '/b', name: 'b', component })
48+
matcher.addRoute('parent', { path: 'b', name: 'p-b', component })
49+
matcher.addRoute('child', { path: 'b', name: 'p-c-b', component })
50+
51+
expect(matcher.match('/b').name).toBe('b')
52+
expect(matcher.match('/p/b').name).toBe('p-b')
53+
expect(matcher.match('/p/c/b').name).toBe('p-c-b')
54+
expect(matcher.match('/p/c/n').name).toBe('nested')
55+
})
56+
2557
it('in development, has logged a warning if a named route does not exist', function () {
2658
process.env.NODE_ENV = 'development'
2759
const { name, matched } = match({ name: 'bar' }, routes[0])

0 commit comments

Comments
 (0)