Skip to content

Commit 0e0fac9

Browse files
committed
add router.addRoutes() feature
1 parent 5593207 commit 0e0fac9

File tree

9 files changed

+77
-10
lines changed

9 files changed

+77
-10
lines changed

src/components/link.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { _Vue } from '../install'
55

66
// work around weird flow bug
77
const toTypes: Array<Function> = [String, Object]
8+
const eventTypes: Array<Function> = [String, Array]
89

910
export default {
1011
name: 'router-link',
@@ -22,7 +23,7 @@ export default {
2223
replace: Boolean,
2324
activeClass: String,
2425
event: {
25-
type: [String, Array],
26+
type: eventTypes,
2627
default: 'click'
2728
}
2829
},

src/components/view.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ function resolveProps (route, config) {
7575
case 'function':
7676
return config(route)
7777
case 'boolean':
78-
if (config) {
79-
return route.params
80-
}
78+
return config ? route.params : undefined
8179
default:
8280
warn(false, `props in "${route.path}" is a ${typeof config}, expecting an object, function or boolean.`)
8381
}

src/history/abstract.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export class AbstractHistory extends History {
3838
})
3939
}
4040

41+
getCurrentLocation () {
42+
const current = this.stack[this.stack.length - 1]
43+
return current ? current.fullPath : '/'
44+
}
45+
4146
ensureURL () {
4247
// noop
4348
}

src/history/base.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class History {
1919
push: (loc: RawLocation) => void;
2020
replace: (loc: RawLocation) => void;
2121
ensureURL: (push?: boolean) => void;
22+
getCurrentLocation: () => string;
2223

2324
constructor (router: VueRouter, base: ?string) {
2425
this.router = router
@@ -44,7 +45,11 @@ export class History {
4445
confirmTransition (route: Route, onComplete: Function, onAbort?: Function) {
4546
const current = this.current
4647
const abort = () => { onAbort && onAbort() }
47-
if (isSameRoute(route, current)) {
48+
if (
49+
isSameRoute(route, current) &&
50+
// in the case the route map has been dynamically appended to
51+
route.matched.length === current.matched.length
52+
) {
4853
this.ensureURL()
4954
return abort()
5055
}

src/history/hash.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ export class HashHistory extends History {
5656
push ? pushHash(current) : replaceHash(current)
5757
}
5858
}
59+
60+
getCurrentLocation () {
61+
return getHash()
62+
}
5963
}
6064

6165
function ensureSlash (): boolean {

src/history/html5.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ export class HTML5History extends History {
7070
}
7171
}
7272

73+
getCurrentLocation (): string {
74+
return getLocation(this.base)
75+
}
76+
7377
handleScroll (to: Route, from: Route, isPop: boolean) {
7478
const router = this.router
7579
if (!router.app) {

src/index.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
import { install } from './install'
44
import { createMatcher } from './create-matcher'
5-
import { HashHistory, getHash } from './history/hash'
6-
import { HTML5History, getLocation } from './history/html5'
5+
import { HashHistory } from './history/hash'
6+
import { HTML5History } from './history/html5'
77
import { AbstractHistory } from './history/abstract'
88
import { inBrowser, supportsHistory } from './util/dom'
99
import { assert } from './util/warn'
1010
import { cleanPath } from './util/path'
1111
import { normalizeLocation } from './util/location'
12+
import { START } from './util/route'
1213

1314
export default class VueRouter {
1415
static install: () => void;
@@ -51,7 +52,9 @@ export default class VueRouter {
5152
this.history = new AbstractHistory(this, options.base)
5253
break
5354
default:
54-
process.env.NODE_ENV !== 'production' && assert(false, `invalid mode: ${mode}`)
55+
if (process.env.NODE_ENV !== 'production') {
56+
assert(false, `invalid mode: ${mode}`)
57+
}
5558
}
5659
}
5760

@@ -71,14 +74,18 @@ export default class VueRouter {
7174
const history = this.history
7275

7376
if (history instanceof HTML5History) {
74-
history.transitionTo(getLocation(history.base))
77+
history.transitionTo(history.getCurrentLocation())
7578
} else if (history instanceof HashHistory) {
7679
const setupHashListener = () => {
7780
window.addEventListener('hashchange', () => {
7881
history.onHashChange()
7982
})
8083
}
81-
history.transitionTo(getHash(), setupHashListener, setupHashListener)
84+
history.transitionTo(
85+
history.getCurrentLocation(),
86+
setupHashListener,
87+
setupHashListener
88+
)
8289
}
8390

8491
history.listen(route => {
@@ -148,6 +155,14 @@ export default class VueRouter {
148155
href
149156
}
150157
}
158+
159+
addRoutes (routes: Array<RouteConfig>) {
160+
routes = this.options.routes = (this.options.routes || []).concat(routes)
161+
this.match = createMatcher(routes)
162+
if (this.history.current !== START) {
163+
this.history.transitionTo(this.history.getCurrentLocation())
164+
}
165+
}
151166
}
152167

153168
function createHref (base: string, fullPath: string, mode) {

test/unit/specs/add-routes.spec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import Router from '../../../src/index'
2+
3+
describe('router.addRoutes', () => {
4+
it('should work', () => {
5+
const router = new Router({
6+
mode: 'abstract',
7+
routes: [
8+
{ path: '/a', component: { name: 'A' }}
9+
]
10+
})
11+
12+
router.push('/a')
13+
let components = router.getMatchedComponents()
14+
expect(components.length).toBe(1)
15+
expect(components[0].name).toBe('A')
16+
17+
router.push('/b')
18+
components = router.getMatchedComponents()
19+
expect(components.length).toBe(0)
20+
21+
router.addRoutes([
22+
{ path: '/b', component: { name: 'B' }}
23+
])
24+
components = router.getMatchedComponents()
25+
expect(components.length).toBe(1)
26+
expect(components[0].name).toBe('B')
27+
28+
// make sure it preserves previous routes
29+
router.push('/a')
30+
components = router.getMatchedComponents()
31+
expect(components.length).toBe(1)
32+
expect(components[0].name).toBe('A')
33+
})
34+
})

types/router.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ declare class VueRouter {
2828
back (): void;
2929
forward (): void;
3030
getMatchedComponents (to?: RawLocation): Component[];
31+
addRoutes (routes: RouteConfig[]): void;
3132
resolve (to: RawLocation, current?: Route, append?: boolean): {
3233
normalizedTo: Location;
3334
resolved: Route;

0 commit comments

Comments
 (0)