Skip to content

Commit 0ed4540

Browse files
committed
api change to make sure route is present on first render
1 parent bf33688 commit 0ed4540

File tree

1 file changed

+86
-54
lines changed

1 file changed

+86
-54
lines changed

src/index.js

+86-54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
var Recognizer = require('route-recognizer')
22
var hasPushState = typeof history !== 'undefined' && history.pushState
3+
var installed = false
4+
var Vue
35

46
/**
57
* Router constructor
@@ -11,9 +13,9 @@ var hasPushState = typeof history !== 'undefined' && history.pushState
1113
*/
1214

1315
function VueRouter (options) {
16+
this.app = null
1417
this._recognizer = new Recognizer()
1518
this._started = false
16-
this._vm = null
1719
this._currentPath = null
1820
this._notfoundHandler = null
1921
this._root = null
@@ -31,13 +33,29 @@ function VueRouter (options) {
3133
this._pushstate = !!(hasPushState && options && options.pushstate)
3234
}
3335

34-
var p = VueRouter.prototype
36+
/**
37+
* Installation interface.
38+
* Install the necessary directives.
39+
*/
40+
41+
VueRouter.install = function (ExternalVue) {
42+
if (installed) {
43+
warn('vue-router has already been installed.')
44+
return
45+
}
46+
Vue = ExternalVue
47+
installed = true
48+
require('./view')(Vue)
49+
require('./link')(Vue)
50+
}
3551

3652
//
3753
// Public API
3854
//
3955
//
4056

57+
var p = VueRouter.prototype
58+
4159
/**
4260
* Register a map of top-level paths.
4361
*/
@@ -123,34 +141,64 @@ p.go = function (path, options) {
123141
/**
124142
* Start the router.
125143
*
126-
* @param {Vue} vm
144+
* @param {VueConstructor} App
145+
* @param {String|Element} container
127146
*/
128147

129-
p.start = function (vm) {
148+
p.start = function (App, container) {
149+
if (!installed) {
150+
throw new Error(
151+
'Please install vue-router with Vue.use() before ' +
152+
'starting the router.'
153+
)
154+
}
130155
if (this._started) {
156+
warn('vue-router has already been started.')
131157
return
132158
}
133159
this._started = true
134-
this._vm = this._vm || vm
135-
if (!this._vm) {
136-
throw new Error(
137-
'vue-router must be started with a root Vue instance.'
138-
)
160+
if (!this.app) {
161+
if (!App || !container) {
162+
throw new Error(
163+
'Must start vue-router with a component and a ' +
164+
'root container.'
165+
)
166+
}
167+
this._appContainer = container
168+
this._appConstructor = typeof App === 'function'
169+
? App
170+
: Vue.extend(App)
139171
}
140172
if (this._pushstate) {
141-
this.initHistoryMode()
173+
this._initHistoryMode()
142174
} else {
143-
this.initHashMode()
175+
this._initHashMode()
144176
}
145177
}
146178

179+
/**
180+
* Stop listening to route changes.
181+
*/
182+
183+
p.stop = function () {
184+
var event = this._pushstate
185+
? 'popstate'
186+
: 'hashchange'
187+
window.removeEventListener(event, this._onRouteChange)
188+
this._started = false
189+
}
190+
191+
//
192+
// Private Methods
193+
//
194+
147195
/**
148196
* Initialize hash mode.
149197
*/
150198

151-
p.initHashMode = function () {
199+
p._initHashMode = function () {
152200
var self = this
153-
this.onRouteChange = function () {
201+
this._onRouteChange = function () {
154202
// format hashbang
155203
var hash = location.hash
156204
if (self._hashbang && hash && hash.charAt(1) !== '!') {
@@ -166,42 +214,25 @@ p.initHashMode = function () {
166214
url = decodeURI(url)
167215
self._match(url)
168216
}
169-
window.addEventListener('hashchange', this.onRouteChange)
170-
this.onRouteChange()
217+
window.addEventListener('hashchange', this._onRouteChange)
218+
this._onRouteChange()
171219
}
172220

173221
/**
174222
* Initialize HTML5 history mode.
175223
*/
176224

177-
p.initHistoryMode = function () {
225+
p._initHistoryMode = function () {
178226
var self = this
179-
this.onRouteChange = function () {
227+
this._onRouteChange = function () {
180228
var url = location.pathname + location.search
181229
url = decodeURI(url)
182230
self._match(url)
183231
}
184-
window.addEventListener('popstate', this.onRouteChange)
185-
this.onRouteChange()
186-
}
187-
188-
/**
189-
* Stop listening to route changes.
190-
*/
191-
192-
p.stop = function () {
193-
var event = this._pushstate
194-
? 'popstate'
195-
: 'hashchange'
196-
window.removeEventListener(event, this.onRouteChange)
197-
this._vm.route = null
198-
this._started = false
232+
window.addEventListener('popstate', this._onRouteChange)
233+
this._onRouteChange()
199234
}
200235

201-
//
202-
// Private Methods
203-
//
204-
205236
/**
206237
* Add a route containing a list of segments to the internal
207238
* route recognizer. Will be called recursively to add all
@@ -211,6 +242,7 @@ p.stop = function () {
211242
* @param {Object} config
212243
* @param {Array} segments
213244
*/
245+
214246
p._addRoute = function (path, config, segments) {
215247
segments.push({
216248
path: path,
@@ -237,6 +269,7 @@ p._addRoute = function (path, config, segments) {
237269
*
238270
* @param {String} path
239271
*/
272+
240273
p._match = function (path) {
241274
if (path === this._currentPath) {
242275
return
@@ -272,7 +305,16 @@ p._match = function (path) {
272305
_matchedCount: 0,
273306
_router: this
274307
}
275-
this._vm.$set('route', context)
308+
if (!this.app) {
309+
this.app = new this._appConstructor({
310+
el: this._appContainer,
311+
data: {
312+
route: context
313+
}
314+
})
315+
} else {
316+
this.app.route = context
317+
}
276318
}
277319

278320
/**
@@ -281,6 +323,7 @@ p._match = function (path) {
281323
* @param {String} hash
282324
* @param {Boolean} replace
283325
*/
326+
284327
function setHash (hash, replace) {
285328
if (replace) {
286329
var urlLength = location.href.length - location.hash.length
@@ -292,26 +335,15 @@ function setHash (hash, replace) {
292335
}
293336

294337
/**
295-
* Installation interface.
296-
* Install the necessary directives.
338+
* Warning (check console for IE9)
339+
*
340+
* @param {String} msg
297341
*/
298342

299-
var installed = false
300-
VueRouter.install = function (Vue) {
301-
if (installed) {
302-
Vue.util.warn && Vue.util.warn(
303-
'vue-router has already been installed.'
304-
)
305-
return
343+
function warn (msg) {
344+
if (typeof console !== 'undefined') {
345+
console.warn(msg)
306346
}
307-
installed = true
308-
require('./view')(Vue)
309-
require('./link')(Vue)
310-
}
311-
312-
// Auto-install if loaded
313-
if (typeof Vue !== 'undefined') {
314-
Vue.use(VueRouter)
315347
}
316348

317349
module.exports = VueRouter

0 commit comments

Comments
 (0)