首页 > 语言 > JavaScript > 正文

简化版的vue-router实现思路详解

2024-05-06 15:28:35
字体:
来源:转载
供稿:网友

本文旨在介绍 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;}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选