@@ -6,21 +6,18 @@ export default class Router {
6
6
constructor ( initialData ) {
7
7
this . subscriptions = [ ]
8
8
9
- const { Component } = initialData
10
- const { pathname } = location
11
- const route = toRoute ( pathname )
9
+ const id = createUid ( )
10
+ const route = toRoute ( location . pathname )
12
11
13
12
this . currentRoute = route
14
- this . currentComponent = Component . displayName
15
- this . currentComponentData = initialData
13
+ this . currentComponentData = { ...initialData , id }
16
14
17
15
// set up the component cache (by route keys)
18
16
this . components = { [ route ] : initialData }
19
17
20
18
// in order for `e.state` to work on the `onpopstate` event
21
19
// we have to register the initial route upon initialization
22
- const url = pathname + ( location . search || '' ) + ( location . hash || '' )
23
- this . replace ( Component , url )
20
+ this . replace ( id , getURL ( ) )
24
21
25
22
this . onPopState = this . onPopState . bind ( this )
26
23
window . addEventListener ( 'unload' , ( ) => { } )
@@ -30,8 +27,7 @@ export default class Router {
30
27
onPopState ( e ) {
31
28
this . abortComponentLoad ( )
32
29
const cur = this . currentComponent
33
- const pathname = location . pathname
34
- const url = pathname + ( location . search || '' ) + ( location . hash || '' )
30
+ const url = getURL ( )
35
31
const { fromComponent, route } = e . state || { }
36
32
if ( fromComponent && cur && fromComponent === cur ) {
37
33
// if the component has not changed due
@@ -47,7 +43,7 @@ export default class Router {
47
43
// since the URL has already changed
48
44
location . reload ( )
49
45
} else {
50
- this . currentRoute = route || toRoute ( pathname )
46
+ this . currentRoute = route || toRoute ( location . pathname )
51
47
this . currentComponent = data . Component . displayName
52
48
this . currentComponentData = data
53
49
this . set ( url )
@@ -88,40 +84,31 @@ export default class Router {
88
84
this . change ( 'pushState' , fromComponent , url , fn )
89
85
}
90
86
91
- replace ( fromComponent , url , fn ) {
92
- this . change ( 'replaceState' , fromComponent , url , fn )
87
+ replace ( id , url , fn ) {
88
+ this . change ( 'replaceState' , id , url , fn )
93
89
}
94
90
95
- change ( method , component , url , fn ) {
91
+ change ( method , id , url , fn ) {
96
92
this . abortComponentLoad ( )
97
93
98
- const set = ( name ) => {
99
- this . currentComponent = name
100
- const state = name
101
- ? { fromComponent : name , route : this . currentRoute }
102
- : { }
94
+ const set = ( id ) => {
95
+ const state = id ? { fromComponent : id , route : this . currentRoute } : { }
103
96
history [ method ] ( state , null , url )
104
97
this . set ( url )
105
98
if ( fn ) fn ( null )
106
99
}
107
100
108
- const componentName = component && component . displayName
109
- if ( component && ! componentName ) {
110
- throw new Error ( 'Initial component must have a unique `displayName`' )
111
- }
112
-
113
- if ( this . currentComponent &&
114
- componentName !== this . currentComponent ) {
101
+ if ( this . currentComponentData && id !== this . currentComponentData . id ) {
115
102
this . fetchComponent ( url , ( err , data ) => {
116
103
if ( ! err ) {
117
104
this . currentRoute = toRoute ( url )
118
105
this . currentComponentData = data
119
- set ( data . Component . displayName )
106
+ set ( data . id )
120
107
}
121
108
if ( fn ) fn ( err , data )
122
109
} )
123
110
} else {
124
- set ( componentName )
111
+ set ( id )
125
112
}
126
113
}
127
114
@@ -139,7 +126,7 @@ export default class Router {
139
126
}
140
127
141
128
fetchComponent ( url , fn ) {
142
- const pathname = parse ( url , true )
129
+ const { pathname } = parse ( url )
143
130
const route = toRoute ( pathname )
144
131
145
132
let cancelled = false
@@ -174,11 +161,12 @@ export default class Router {
174
161
if ( err ) {
175
162
if ( ! cancelled ) fn ( err )
176
163
} else {
164
+ const d = { data, id : createUid ( ) }
177
165
// we update the cache even if cancelled
178
166
if ( ! this . components [ route ] ) {
179
- this . components [ route ] = data
167
+ this . components [ route ] = d
180
168
}
181
- if ( ! cancelled ) fn ( null , data )
169
+ if ( ! cancelled ) fn ( null , d )
182
170
}
183
171
} )
184
172
@@ -224,6 +212,14 @@ export function loadComponent (url, fn) {
224
212
} )
225
213
}
226
214
215
+ function getURL ( ) {
216
+ return location . pathname + ( location . search || '' ) + ( location . hash || '' )
217
+ }
218
+
219
+ function createUid ( ) {
220
+ return Math . floor ( Math . random ( ) * 1e16 )
221
+ }
222
+
227
223
function loadJSON ( url , fn ) {
228
224
const xhr = new XMLHttpRequest ( )
229
225
xhr . onload = ( ) => {
0 commit comments