kdu-router 3.1.3 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +20 -56
- package/dist/kdu-router.common.js +2917 -2881
- package/dist/kdu-router.esm.browser.js +2867 -2831
- package/dist/kdu-router.esm.browser.min.js +11 -6
- package/dist/kdu-router.esm.js +2915 -2879
- package/dist/kdu-router.js +2923 -2887
- package/dist/kdu-router.min.js +11 -6
- package/package.json +81 -107
- package/src/components/link.js +190 -0
- package/src/components/view.js +149 -0
- package/src/create-matcher.js +200 -200
- package/src/create-route-map.js +205 -205
- package/src/history/abstract.js +69 -0
- package/src/history/base.js +352 -0
- package/src/history/errors.js +22 -0
- package/src/history/hash.js +154 -0
- package/src/history/html5.js +80 -0
- package/src/index.js +261 -261
- package/src/install.js +52 -52
- package/src/util/async.js +18 -0
- package/src/util/dom.js +3 -0
- package/src/util/location.js +69 -0
- package/src/util/misc.js +6 -0
- package/src/util/params.js +37 -0
- package/src/util/path.js +74 -0
- package/src/util/push-state.js +46 -0
- package/src/util/query.js +95 -0
- package/src/util/resolve-components.js +108 -0
- package/src/util/route.js +132 -0
- package/src/util/scroll.js +156 -0
- package/src/util/state-key.js +22 -0
- package/src/util/warn.js +25 -0
- package/types/index.d.ts +16 -16
- package/types/kdu.d.ts +22 -22
- package/types/router.d.ts +145 -145
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { warn } from '../util/warn'
|
|
2
|
+
import { extend } from '../util/misc'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: 'RouterView',
|
|
6
|
+
functional: true,
|
|
7
|
+
props: {
|
|
8
|
+
name: {
|
|
9
|
+
type: String,
|
|
10
|
+
default: 'default'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
render (_, { props, children, parent, data }) {
|
|
14
|
+
// used by devtools to display a router-view badge
|
|
15
|
+
data.routerView = true
|
|
16
|
+
|
|
17
|
+
// directly use parent context's createElement() function
|
|
18
|
+
// so that components rendered by router-view can resolve named slots
|
|
19
|
+
const h = parent.$createElement
|
|
20
|
+
const name = props.name
|
|
21
|
+
const route = parent.$route
|
|
22
|
+
const cache = parent._routerViewCache || (parent._routerViewCache = {})
|
|
23
|
+
|
|
24
|
+
// determine current view depth, also check to see if the tree
|
|
25
|
+
// has been toggled inactive but kept-alive.
|
|
26
|
+
let depth = 0
|
|
27
|
+
let inactive = false
|
|
28
|
+
while (parent && parent._routerRoot !== parent) {
|
|
29
|
+
const knodeData = parent.$knode ? parent.$knode.data : {}
|
|
30
|
+
if (knodeData.routerView) {
|
|
31
|
+
depth++
|
|
32
|
+
}
|
|
33
|
+
if (knodeData.keepAlive && parent._directInactive && parent._inactive) {
|
|
34
|
+
inactive = true
|
|
35
|
+
}
|
|
36
|
+
parent = parent.$parent
|
|
37
|
+
}
|
|
38
|
+
data.routerViewDepth = depth
|
|
39
|
+
|
|
40
|
+
// render previous view if the tree is inactive and kept-alive
|
|
41
|
+
if (inactive) {
|
|
42
|
+
const cachedData = cache[name]
|
|
43
|
+
const cachedComponent = cachedData && cachedData.component
|
|
44
|
+
if (cachedComponent) {
|
|
45
|
+
// #2301
|
|
46
|
+
// pass props
|
|
47
|
+
if (cachedData.configProps) {
|
|
48
|
+
fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps)
|
|
49
|
+
}
|
|
50
|
+
return h(cachedComponent, data, children)
|
|
51
|
+
} else {
|
|
52
|
+
// render previous empty view
|
|
53
|
+
return h()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const matched = route.matched[depth]
|
|
58
|
+
const component = matched && matched.components[name]
|
|
59
|
+
|
|
60
|
+
// render empty node if no matched route or no config component
|
|
61
|
+
if (!matched || !component) {
|
|
62
|
+
cache[name] = null
|
|
63
|
+
return h()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// cache component
|
|
67
|
+
cache[name] = { component }
|
|
68
|
+
|
|
69
|
+
// attach instance registration hook
|
|
70
|
+
// this will be called in the instance's injected lifecycle hooks
|
|
71
|
+
data.registerRouteInstance = (vm, val) => {
|
|
72
|
+
// val could be undefined for unregistration
|
|
73
|
+
const current = matched.instances[name]
|
|
74
|
+
if (
|
|
75
|
+
(val && current !== vm) ||
|
|
76
|
+
(!val && current === vm)
|
|
77
|
+
) {
|
|
78
|
+
matched.instances[name] = val
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// also register instance in prepatch hook
|
|
83
|
+
// in case the same component instance is reused across different routes
|
|
84
|
+
;(data.hook || (data.hook = {})).prepatch = (_, knode) => {
|
|
85
|
+
matched.instances[name] = knode.componentInstance
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// register instance in init hook
|
|
89
|
+
// in case kept-alive component be actived when routes changed
|
|
90
|
+
data.hook.init = (knode) => {
|
|
91
|
+
if (knode.data.keepAlive &&
|
|
92
|
+
knode.componentInstance &&
|
|
93
|
+
knode.componentInstance !== matched.instances[name]
|
|
94
|
+
) {
|
|
95
|
+
matched.instances[name] = knode.componentInstance
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const configProps = matched.props && matched.props[name]
|
|
100
|
+
// save route and configProps in cachce
|
|
101
|
+
if (configProps) {
|
|
102
|
+
extend(cache[name], {
|
|
103
|
+
route,
|
|
104
|
+
configProps
|
|
105
|
+
})
|
|
106
|
+
fillPropsinData(component, data, route, configProps)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return h(component, data, children)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function fillPropsinData (component, data, route, configProps) {
|
|
114
|
+
// resolve props
|
|
115
|
+
let propsToPass = data.props = resolveProps(route, configProps)
|
|
116
|
+
if (propsToPass) {
|
|
117
|
+
// clone to prevent mutation
|
|
118
|
+
propsToPass = data.props = extend({}, propsToPass)
|
|
119
|
+
// pass non-declared props as attrs
|
|
120
|
+
const attrs = data.attrs = data.attrs || {}
|
|
121
|
+
for (const key in propsToPass) {
|
|
122
|
+
if (!component.props || !(key in component.props)) {
|
|
123
|
+
attrs[key] = propsToPass[key]
|
|
124
|
+
delete propsToPass[key]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function resolveProps (route, config) {
|
|
131
|
+
switch (typeof config) {
|
|
132
|
+
case 'undefined':
|
|
133
|
+
return
|
|
134
|
+
case 'object':
|
|
135
|
+
return config
|
|
136
|
+
case 'function':
|
|
137
|
+
return config(route)
|
|
138
|
+
case 'boolean':
|
|
139
|
+
return config ? route.params : undefined
|
|
140
|
+
default:
|
|
141
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
142
|
+
warn(
|
|
143
|
+
false,
|
|
144
|
+
`props in "${route.path}" is a ${typeof config}, ` +
|
|
145
|
+
`expecting an object, function or boolean.`
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
package/src/create-matcher.js
CHANGED
|
@@ -1,200 +1,200 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import type KduRouter from './index'
|
|
4
|
-
import { resolvePath } from './util/path'
|
|
5
|
-
import { assert, warn } from './util/warn'
|
|
6
|
-
import { createRoute } from './util/route'
|
|
7
|
-
import { fillParams } from './util/params'
|
|
8
|
-
import { createRouteMap } from './create-route-map'
|
|
9
|
-
import { normalizeLocation } from './util/location'
|
|
10
|
-
|
|
11
|
-
export type Matcher = {
|
|
12
|
-
match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
|
|
13
|
-
addRoutes: (routes: Array<RouteConfig>) => void;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function createMatcher (
|
|
17
|
-
routes: Array<RouteConfig>,
|
|
18
|
-
router: KduRouter
|
|
19
|
-
): Matcher {
|
|
20
|
-
const { pathList, pathMap, nameMap } = createRouteMap(routes)
|
|
21
|
-
|
|
22
|
-
function addRoutes (routes) {
|
|
23
|
-
createRouteMap(routes, pathList, pathMap, nameMap)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function match (
|
|
27
|
-
raw: RawLocation,
|
|
28
|
-
currentRoute?: Route,
|
|
29
|
-
redirectedFrom?: Location
|
|
30
|
-
): Route {
|
|
31
|
-
const location = normalizeLocation(raw, currentRoute, false, router)
|
|
32
|
-
const { name } = location
|
|
33
|
-
|
|
34
|
-
if (name) {
|
|
35
|
-
const record = nameMap[name]
|
|
36
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
37
|
-
warn(record, `Route with name '${name}' does not exist`)
|
|
38
|
-
}
|
|
39
|
-
if (!record) return _createRoute(null, location)
|
|
40
|
-
const paramNames = record.regex.keys
|
|
41
|
-
.filter(key => !key.optional)
|
|
42
|
-
.map(key => key.name)
|
|
43
|
-
|
|
44
|
-
if (typeof location.params !== 'object') {
|
|
45
|
-
location.params = {}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (currentRoute && typeof currentRoute.params === 'object') {
|
|
49
|
-
for (const key in currentRoute.params) {
|
|
50
|
-
if (!(key in location.params) && paramNames.indexOf(key) > -1) {
|
|
51
|
-
location.params[key] = currentRoute.params[key]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
location.path = fillParams(record.path, location.params, `named route "${name}"`)
|
|
57
|
-
return _createRoute(record, location, redirectedFrom)
|
|
58
|
-
} else if (location.path) {
|
|
59
|
-
location.params = {}
|
|
60
|
-
for (let i = 0; i < pathList.length; i++) {
|
|
61
|
-
const path = pathList[i]
|
|
62
|
-
const record = pathMap[path]
|
|
63
|
-
if (matchRoute(record.regex, location.path, location.params)) {
|
|
64
|
-
return _createRoute(record, location, redirectedFrom)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// no match
|
|
69
|
-
return _createRoute(null, location)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function redirect (
|
|
73
|
-
record: RouteRecord,
|
|
74
|
-
location: Location
|
|
75
|
-
): Route {
|
|
76
|
-
const originalRedirect = record.redirect
|
|
77
|
-
let redirect = typeof originalRedirect === 'function'
|
|
78
|
-
? originalRedirect(createRoute(record, location, null, router))
|
|
79
|
-
: originalRedirect
|
|
80
|
-
|
|
81
|
-
if (typeof redirect === 'string') {
|
|
82
|
-
redirect = { path: redirect }
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!redirect || typeof redirect !== 'object') {
|
|
86
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
87
|
-
warn(
|
|
88
|
-
false, `invalid redirect option: ${JSON.stringify(redirect)}`
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
return _createRoute(null, location)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const re: Object = redirect
|
|
95
|
-
const { name, path } = re
|
|
96
|
-
let { query, hash, params } = location
|
|
97
|
-
query = re.hasOwnProperty('query') ? re.query : query
|
|
98
|
-
hash = re.hasOwnProperty('hash') ? re.hash : hash
|
|
99
|
-
params = re.hasOwnProperty('params') ? re.params : params
|
|
100
|
-
|
|
101
|
-
if (name) {
|
|
102
|
-
// resolved named direct
|
|
103
|
-
const targetRecord = nameMap[name]
|
|
104
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
105
|
-
assert(targetRecord, `redirect failed: named route "${name}" not found.`)
|
|
106
|
-
}
|
|
107
|
-
return match({
|
|
108
|
-
_normalized: true,
|
|
109
|
-
name,
|
|
110
|
-
query,
|
|
111
|
-
hash,
|
|
112
|
-
params
|
|
113
|
-
}, undefined, location)
|
|
114
|
-
} else if (path) {
|
|
115
|
-
// 1. resolve relative redirect
|
|
116
|
-
const rawPath = resolveRecordPath(path, record)
|
|
117
|
-
// 2. resolve params
|
|
118
|
-
const resolvedPath = fillParams(rawPath, params, `redirect route with path "${rawPath}"`)
|
|
119
|
-
// 3. rematch with existing query and hash
|
|
120
|
-
return match({
|
|
121
|
-
_normalized: true,
|
|
122
|
-
path: resolvedPath,
|
|
123
|
-
query,
|
|
124
|
-
hash
|
|
125
|
-
}, undefined, location)
|
|
126
|
-
} else {
|
|
127
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
128
|
-
warn(false, `invalid redirect option: ${JSON.stringify(redirect)}`)
|
|
129
|
-
}
|
|
130
|
-
return _createRoute(null, location)
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function alias (
|
|
135
|
-
record: RouteRecord,
|
|
136
|
-
location: Location,
|
|
137
|
-
matchAs: string
|
|
138
|
-
): Route {
|
|
139
|
-
const aliasedPath = fillParams(matchAs, location.params, `aliased route with path "${matchAs}"`)
|
|
140
|
-
const aliasedMatch = match({
|
|
141
|
-
_normalized: true,
|
|
142
|
-
path: aliasedPath
|
|
143
|
-
})
|
|
144
|
-
if (aliasedMatch) {
|
|
145
|
-
const matched = aliasedMatch.matched
|
|
146
|
-
const aliasedRecord = matched[matched.length - 1]
|
|
147
|
-
location.params = aliasedMatch.params
|
|
148
|
-
return _createRoute(aliasedRecord, location)
|
|
149
|
-
}
|
|
150
|
-
return _createRoute(null, location)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function _createRoute (
|
|
154
|
-
record: ?RouteRecord,
|
|
155
|
-
location: Location,
|
|
156
|
-
redirectedFrom?: Location
|
|
157
|
-
): Route {
|
|
158
|
-
if (record && record.redirect) {
|
|
159
|
-
return redirect(record, redirectedFrom || location)
|
|
160
|
-
}
|
|
161
|
-
if (record && record.matchAs) {
|
|
162
|
-
return alias(record, location, record.matchAs)
|
|
163
|
-
}
|
|
164
|
-
return createRoute(record, location, redirectedFrom, router)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
match,
|
|
169
|
-
addRoutes
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function matchRoute (
|
|
174
|
-
regex: RouteRegExp,
|
|
175
|
-
path: string,
|
|
176
|
-
params: Object
|
|
177
|
-
): boolean {
|
|
178
|
-
const m = path.match(regex)
|
|
179
|
-
|
|
180
|
-
if (!m) {
|
|
181
|
-
return false
|
|
182
|
-
} else if (!params) {
|
|
183
|
-
return true
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
for (let i = 1, len = m.length; i < len; ++i) {
|
|
187
|
-
const key = regex.keys[i - 1]
|
|
188
|
-
const val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]
|
|
189
|
-
if (key) {
|
|
190
|
-
// Fix #1994: using * with props: true generates a param named 0
|
|
191
|
-
params[key.name || 'pathMatch'] = val
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return true
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function resolveRecordPath (path: string, record: RouteRecord): string {
|
|
199
|
-
return resolvePath(path, record.parent ? record.parent.path : '/', true)
|
|
200
|
-
}
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
import type KduRouter from './index'
|
|
4
|
+
import { resolvePath } from './util/path'
|
|
5
|
+
import { assert, warn } from './util/warn'
|
|
6
|
+
import { createRoute } from './util/route'
|
|
7
|
+
import { fillParams } from './util/params'
|
|
8
|
+
import { createRouteMap } from './create-route-map'
|
|
9
|
+
import { normalizeLocation } from './util/location'
|
|
10
|
+
|
|
11
|
+
export type Matcher = {
|
|
12
|
+
match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
|
|
13
|
+
addRoutes: (routes: Array<RouteConfig>) => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function createMatcher (
|
|
17
|
+
routes: Array<RouteConfig>,
|
|
18
|
+
router: KduRouter
|
|
19
|
+
): Matcher {
|
|
20
|
+
const { pathList, pathMap, nameMap } = createRouteMap(routes)
|
|
21
|
+
|
|
22
|
+
function addRoutes (routes) {
|
|
23
|
+
createRouteMap(routes, pathList, pathMap, nameMap)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function match (
|
|
27
|
+
raw: RawLocation,
|
|
28
|
+
currentRoute?: Route,
|
|
29
|
+
redirectedFrom?: Location
|
|
30
|
+
): Route {
|
|
31
|
+
const location = normalizeLocation(raw, currentRoute, false, router)
|
|
32
|
+
const { name } = location
|
|
33
|
+
|
|
34
|
+
if (name) {
|
|
35
|
+
const record = nameMap[name]
|
|
36
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
37
|
+
warn(record, `Route with name '${name}' does not exist`)
|
|
38
|
+
}
|
|
39
|
+
if (!record) return _createRoute(null, location)
|
|
40
|
+
const paramNames = record.regex.keys
|
|
41
|
+
.filter(key => !key.optional)
|
|
42
|
+
.map(key => key.name)
|
|
43
|
+
|
|
44
|
+
if (typeof location.params !== 'object') {
|
|
45
|
+
location.params = {}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (currentRoute && typeof currentRoute.params === 'object') {
|
|
49
|
+
for (const key in currentRoute.params) {
|
|
50
|
+
if (!(key in location.params) && paramNames.indexOf(key) > -1) {
|
|
51
|
+
location.params[key] = currentRoute.params[key]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
location.path = fillParams(record.path, location.params, `named route "${name}"`)
|
|
57
|
+
return _createRoute(record, location, redirectedFrom)
|
|
58
|
+
} else if (location.path) {
|
|
59
|
+
location.params = {}
|
|
60
|
+
for (let i = 0; i < pathList.length; i++) {
|
|
61
|
+
const path = pathList[i]
|
|
62
|
+
const record = pathMap[path]
|
|
63
|
+
if (matchRoute(record.regex, location.path, location.params)) {
|
|
64
|
+
return _createRoute(record, location, redirectedFrom)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// no match
|
|
69
|
+
return _createRoute(null, location)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function redirect (
|
|
73
|
+
record: RouteRecord,
|
|
74
|
+
location: Location
|
|
75
|
+
): Route {
|
|
76
|
+
const originalRedirect = record.redirect
|
|
77
|
+
let redirect = typeof originalRedirect === 'function'
|
|
78
|
+
? originalRedirect(createRoute(record, location, null, router))
|
|
79
|
+
: originalRedirect
|
|
80
|
+
|
|
81
|
+
if (typeof redirect === 'string') {
|
|
82
|
+
redirect = { path: redirect }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!redirect || typeof redirect !== 'object') {
|
|
86
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
87
|
+
warn(
|
|
88
|
+
false, `invalid redirect option: ${JSON.stringify(redirect)}`
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
return _createRoute(null, location)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const re: Object = redirect
|
|
95
|
+
const { name, path } = re
|
|
96
|
+
let { query, hash, params } = location
|
|
97
|
+
query = re.hasOwnProperty('query') ? re.query : query
|
|
98
|
+
hash = re.hasOwnProperty('hash') ? re.hash : hash
|
|
99
|
+
params = re.hasOwnProperty('params') ? re.params : params
|
|
100
|
+
|
|
101
|
+
if (name) {
|
|
102
|
+
// resolved named direct
|
|
103
|
+
const targetRecord = nameMap[name]
|
|
104
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
105
|
+
assert(targetRecord, `redirect failed: named route "${name}" not found.`)
|
|
106
|
+
}
|
|
107
|
+
return match({
|
|
108
|
+
_normalized: true,
|
|
109
|
+
name,
|
|
110
|
+
query,
|
|
111
|
+
hash,
|
|
112
|
+
params
|
|
113
|
+
}, undefined, location)
|
|
114
|
+
} else if (path) {
|
|
115
|
+
// 1. resolve relative redirect
|
|
116
|
+
const rawPath = resolveRecordPath(path, record)
|
|
117
|
+
// 2. resolve params
|
|
118
|
+
const resolvedPath = fillParams(rawPath, params, `redirect route with path "${rawPath}"`)
|
|
119
|
+
// 3. rematch with existing query and hash
|
|
120
|
+
return match({
|
|
121
|
+
_normalized: true,
|
|
122
|
+
path: resolvedPath,
|
|
123
|
+
query,
|
|
124
|
+
hash
|
|
125
|
+
}, undefined, location)
|
|
126
|
+
} else {
|
|
127
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
128
|
+
warn(false, `invalid redirect option: ${JSON.stringify(redirect)}`)
|
|
129
|
+
}
|
|
130
|
+
return _createRoute(null, location)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function alias (
|
|
135
|
+
record: RouteRecord,
|
|
136
|
+
location: Location,
|
|
137
|
+
matchAs: string
|
|
138
|
+
): Route {
|
|
139
|
+
const aliasedPath = fillParams(matchAs, location.params, `aliased route with path "${matchAs}"`)
|
|
140
|
+
const aliasedMatch = match({
|
|
141
|
+
_normalized: true,
|
|
142
|
+
path: aliasedPath
|
|
143
|
+
})
|
|
144
|
+
if (aliasedMatch) {
|
|
145
|
+
const matched = aliasedMatch.matched
|
|
146
|
+
const aliasedRecord = matched[matched.length - 1]
|
|
147
|
+
location.params = aliasedMatch.params
|
|
148
|
+
return _createRoute(aliasedRecord, location)
|
|
149
|
+
}
|
|
150
|
+
return _createRoute(null, location)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function _createRoute (
|
|
154
|
+
record: ?RouteRecord,
|
|
155
|
+
location: Location,
|
|
156
|
+
redirectedFrom?: Location
|
|
157
|
+
): Route {
|
|
158
|
+
if (record && record.redirect) {
|
|
159
|
+
return redirect(record, redirectedFrom || location)
|
|
160
|
+
}
|
|
161
|
+
if (record && record.matchAs) {
|
|
162
|
+
return alias(record, location, record.matchAs)
|
|
163
|
+
}
|
|
164
|
+
return createRoute(record, location, redirectedFrom, router)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
match,
|
|
169
|
+
addRoutes
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function matchRoute (
|
|
174
|
+
regex: RouteRegExp,
|
|
175
|
+
path: string,
|
|
176
|
+
params: Object
|
|
177
|
+
): boolean {
|
|
178
|
+
const m = path.match(regex)
|
|
179
|
+
|
|
180
|
+
if (!m) {
|
|
181
|
+
return false
|
|
182
|
+
} else if (!params) {
|
|
183
|
+
return true
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
for (let i = 1, len = m.length; i < len; ++i) {
|
|
187
|
+
const key = regex.keys[i - 1]
|
|
188
|
+
const val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]
|
|
189
|
+
if (key) {
|
|
190
|
+
// Fix #1994: using * with props: true generates a param named 0
|
|
191
|
+
params[key.name || 'pathMatch'] = val
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return true
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function resolveRecordPath (path: string, record: RouteRecord): string {
|
|
199
|
+
return resolvePath(path, record.parent ? record.parent.path : '/', true)
|
|
200
|
+
}
|