diff --git a/src/install.js b/src/install.js index ee8506aa8..565b3e7f9 100644 --- a/src/install.js +++ b/src/install.js @@ -22,7 +22,7 @@ export function install (Vue) { beforeCreate () { if (isDef(this.$options.router)) { this._routerRoot = this - this._router = this.$options.router + this._router = typeof this.$options.router === 'function' ? this.$options.router() : this.$options.router this._router.init(this) Vue.util.defineReactive(this, '_route', this._router.history.current) } else { diff --git a/test/unit/specs/factory.spec.js b/test/unit/specs/factory.spec.js new file mode 100644 index 000000000..a8c6f85c1 --- /dev/null +++ b/test/unit/specs/factory.spec.js @@ -0,0 +1,50 @@ +import Router from '../../../src/index' +import Vue from 'vue' + +describe('router factory', () => { + let InstancedBasedApp, FactoryBasedApp + + beforeEach(() => { + const routerFactory = () => new Router({ + mode: 'abstract', + routes: [ + { + path: '/a', + component: { + name: 'A' + } + } + ] + }) + + const router = routerFactory() + + InstancedBasedApp = Vue.extend({ + router, + render (h) { return h('div') } + }) + + FactoryBasedApp = Vue.extend({ + router: routerFactory, + render (h) { return h('div') } + }) + }) + + it('should initialize router from factory', () => { + const vm = new FactoryBasedApp() + expect(vm.$router instanceof Router).toBeTruthy() + }) + + it('should use different router instances on different app instances', () => { + const app = new FactoryBasedApp() + const app2 = new FactoryBasedApp() + expect(app.$router).not.toBe(app2.$router) + }) + + it('should allow to work as normal', () => { + const app = new InstancedBasedApp() + const app2 = new InstancedBasedApp() + expect(app.$router).toBe(app2.$router) + }) +}) + diff --git a/types/vue.d.ts b/types/vue.d.ts index 307515cf9..2b35be25f 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -12,11 +12,12 @@ declare module 'vue/types/vue' { } } -declare module 'vue/types/options' { +declare module "vue/types/options" { + type VueRouterFactory = () => VueRouter; interface ComponentOptions { - router?: VueRouter - beforeRouteEnter?: NavigationGuard - beforeRouteLeave?: NavigationGuard - beforeRouteUpdate?: NavigationGuard + router?: VueRouter | VueRouterFactory; + beforeRouteEnter?: NavigationGuard; + beforeRouteLeave?: NavigationGuard; + beforeRouteUpdate?: NavigationGuard; } }