本文旨在介绍 vue-router 的实现思路,并动手实现一个简化版的 vue-router 。我们先来看一下一般项目中对 vue-router 最基本的一个使用,可以看到,这里定义了四个路由组件,我们只要在根 vue 实例中注入该 router 对象就可以使用了.
import VueRouter from 'vue-router';import Home from '@/components/Home';import A from '@/components/A';import B from '@/components/B'import C from '@/components/C'Vue.use(VueRouter)export default new VueRouter.Router({ // mode: 'history', routes: [ { path: '/', component: Home }, { path: '/a', component: A }, { path: '/b', component: B }, { path: '/c', component: C } ]})
vue-router 提供两个全局组件, router-view
和 router-link
,前者是用于路由组件的占位,后者用于点击时跳转到指定路由。此外组件内部可以通过 this.$router.push , this.$rouer.replace
等api实现路由跳转。本文将实现上述两个全局组件以及 push 和 replace 两个api,调用的时候支持 params 传参,并且支持 hash 和 history 两种模式,忽略其余api、嵌套路由、异步路由、 abstract 路由以及导航守卫等高级功能的实现,这样有助于理解 vue-router 的核心原理。本文的最终代码不建议在生产环境使用,只做一个学习用途,下面我们就来一步步实现它。
install实现
任何一个 vue 插件都要实现一个 install 方法,通过 Vue.use 调用插件的时候就是在调用插件的 install 方法,那么路由的 install 要做哪些事情呢?首先我们知道 我们会用 new 关键字生成一个 router 实例,就像前面的代码实例一样,然后将其挂载到根 vue 实例上,那么作为一个全局路由,我们当然需要在各个组件中都可以拿到这个 router 实例。另外我们使用了全局组件 router-view 和 router-link ,由于 install 会接收到 Vue 构造函数作为实参,方便我们调用 Vue.component 来注册全局组件。因此,在 install 中主要就做两件事,给各个组件都挂载 router 实例,以及实现 router-view
和 router-link
两个全局组件。下面是代码:
const install = (Vue) => { if (this._Vue) { return; }; Vue.mixin({ beforeCreate() { if (this.$options && this.$options.router) { this._routerRoot = this; this._router = this.$options.router; Vue.util.defineReactive(this, '_routeHistory', this._router.history) } else { this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } Object.defineProperty(this, '$router', { get() { return this._routerRoot._router; } }) Object.defineProperty(this, '$route', { get() { return { current: this._routerRoot._routeHistory.current, ...this._routerRoot._router.route }; } }) } }); Vue.component('router-view', { render(h) { ... } }) Vue.component('router-link', { props: { to: String, tag: String, }, render(h) { ... } }) this._Vue = Vue;}
新闻热点
疑难解答
图片精选