From f06679e7ccd944e972c461dcd13e5d801a0548da Mon Sep 17 00:00:00 2001 From: Vito Laera Date: Fri, 31 May 2019 08:44:30 +0200 Subject: [PATCH] feat: allow Vue component to receive a VueRouter factory --- src/install.js | 2 +- test/unit/specs/factory.spec.js | 50 +++++++++++++++++++++++++++++++++ types/vue.d.ts | 3 +- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 test/unit/specs/factory.spec.js 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 4e57eec79..5d322fca5 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -13,8 +13,9 @@ declare module "vue/types/vue" { } declare module "vue/types/options" { + type VueRouterFactory = () => VueRouter; interface ComponentOptions { - router?: VueRouter; + router?: VueRouter | VueRouterFactory; beforeRouteEnter?: NavigationGuard; beforeRouteLeave?: NavigationGuard; beforeRouteUpdate?: NavigationGuard;