Skip to content

Commit 4d0ed4a

Browse files
committed
fix vuejs#922
- Add example for regression/e2e tests - Added test and ensuring that later mounted instance with router takes affect - Install monkey patches Vue.nextTick to VueRouter._nextTick
1 parent 339dc8e commit 4d0ed4a

File tree

7 files changed

+133
-1
lines changed

7 files changed

+133
-1
lines changed

examples/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ <h1>Vue Router Examples</h1>
2222
<li><a href="scroll-behavior">Scroll Behavior</a></li>
2323
<li><a href="lazy-loading">Lazy Loading</a></li>
2424
<li><a href="auth-flow">Auth Flow</a></li>
25+
<li><a href="no-instance">No Vue instance</a></li>
2526
</ul>
2627
</body>
2728
</html>

examples/no-instance/app.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import Vue from 'vue'
2+
import VueRouter from 'vue-router'
3+
4+
// 1. Use plugin.
5+
// This installs <router-view> and <router-link>,
6+
// and injects $router and $route to all router-enabled child components
7+
Vue.use(VueRouter)
8+
9+
// 2. Create the router
10+
// If not mouting the router at runtime you can still invoke router methods
11+
// Route gaurds will still take effect
12+
const router = new VueRouter({
13+
mode: 'history',
14+
base: __dirname,
15+
routes: [
16+
{
17+
path: '/foo',
18+
component: {
19+
template: '<div>foo</div>'
20+
}
21+
},
22+
{
23+
path: '/bar',
24+
component (resolve) {
25+
Vue.nextTick(() => {
26+
resolve({
27+
template: '<div>{{ val }}</div>',
28+
data () {
29+
return {
30+
val: ''
31+
}
32+
},
33+
beforeRouteEnter (to, from, next) {
34+
next((vm) => {
35+
vm.val = 'bar'
36+
})
37+
}
38+
})
39+
})
40+
}
41+
}
42+
]
43+
})
44+
45+
// 3. Use router methods
46+
// You can use router methods prior to instantiation of Vue instance
47+
const locationEl = document.querySelector('.location')
48+
window.handler = (val) => {
49+
if (val === 1) {
50+
router.replace('/foo')
51+
} else if (val === 2) {
52+
router.push('/bar')
53+
} else if (val === 3) {
54+
router.back()
55+
} else if (val === 4) {
56+
router.forward()
57+
} else if (val === 5) {
58+
router.go(-1)
59+
}
60+
setTimeout(() => {
61+
locationEl.innerHTML = window.location.pathname
62+
})
63+
}
64+
65+
// 4. You can mount the router to a Vue instance at any point
66+
window.mount = () => {
67+
new Vue({
68+
router,
69+
template: '<router-view id="mount"/>'
70+
}).$mount('#mount')
71+
}

examples/no-instance/index.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<link rel="stylesheet" href="/global.css">
3+
<a href="/">&larr; Examples index</a>
4+
<div id="app">
5+
<h1>No Vue instance</h1>
6+
<ul>
7+
<li><a onclick="handler(1)">router.replace('/foo')</a></li>
8+
<li><a onclick="handler(2)">router.push('/bar')</a></li>
9+
<li><a onclick="handler(3)">router.back()</a></li>
10+
<li><a onclick="handler(4)">router.forward()</a></li>
11+
<li><a onclick="handler(5)">router.go(-1)</a></li>
12+
</ul>
13+
<p>
14+
<b>Current Location:</b> <span class="location">/</span>
15+
</p>
16+
<button onclick="mount()" id="mount">Mount</button>
17+
</div>
18+
<script src="/__build__/shared.js"></script>
19+
<script src="/__build__/no-instance.js"></script>

src/history/base.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class History {
9292
if (this.pending === route) {
9393
this.pending = null
9494
cb(route)
95-
this.router.app.$nextTick(() => {
95+
this.router._nextTick(() => {
9696
postEnterCbs.forEach(cb => cb())
9797
})
9898
}

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default class VueRouter {
2626
this.beforeHooks = []
2727
this.afterHooks = []
2828
this.match = createMatcher(options.routes || [])
29+
this._nextTick = install._nextTick
2930

3031
let mode = options.mode || 'hash'
3132
this.fallback = mode === 'history' && !supportsHistory

src/install.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export let _Vue
66
export function install (Vue) {
77
if (install.installed) return
88
install.installed = true
9+
install._nextTick = Vue.nextTick
910

1011
_Vue = Vue
1112

test/e2e/specs/no-instance.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module.exports = {
2+
'no-instance': function (browser) {
3+
browser
4+
.url('http://localhost:8080/no-instance/')
5+
.waitForElementVisible('#app', 1000)
6+
7+
// No Vue instance mounted with vue router
8+
.click('li:nth-child(1) > a')
9+
.assert.urlEquals('http://localhost:8080/no-instance/foo')
10+
.assert.containsText('.location', 'no-instance/foo')
11+
12+
.click('li:nth-child(2) > a')
13+
.assert.urlEquals('http://localhost:8080/no-instance/bar')
14+
.assert.containsText('.location', 'no-instance/bar')
15+
16+
.click('li:nth-child(3) > a')
17+
.assert.urlEquals('http://localhost:8080/no-instance/foo')
18+
.assert.containsText('.location', 'no-instance/foo')
19+
20+
.click('li:nth-child(4) > a')
21+
.assert.urlEquals('http://localhost:8080/no-instance/bar')
22+
.assert.containsText('.location', 'no-instance/bar')
23+
24+
.click('li:nth-child(5) > a')
25+
.assert.urlEquals('http://localhost:8080/no-instance/foo')
26+
.assert.containsText('.location', 'no-instance/foo')
27+
28+
// Vue instance mounted with vue router
29+
.click('#mount')
30+
.assert.urlEquals('http://localhost:8080/no-instance/foo')
31+
.assert.containsText('.location', 'no-instance/foo')
32+
.assert.containsText('#mount', 'foo')
33+
34+
.click('li:nth-child(2) > a')
35+
.assert.urlEquals('http://localhost:8080/no-instance/bar')
36+
.assert.containsText('.location', 'no-instance/bar')
37+
.assert.containsText('#mount', 'bar')
38+
}
39+
}

0 commit comments

Comments
 (0)