一、起步需求分析
从添加router插件开始,在执行了vue add router
命令后,项目目录中会增加一个router目录并在main.js中导入router选项。
先从router目录下的index.js开始:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
// 注册VueRouter插件
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
routes
})
// 导出router实例
export default router
从router的index.js文件可以看出,这里做了三件事:
- 注册了VueRouter插件
- 实例化了一个VueRouter类并将route配置传入
- 导出VueRouter实例
在main.js文件中,vue-rotuer的修改:
- 导入router目录下的index.js
- 在Vue实例化时将VueRouter实例当成选项传入
表面上Vue-Router就做了这些事情,但在我们平常开发时,我们可以在每个组件中访问$router
,而在表面上我们并没有发现Vue-Router在main.js中将$router
挂载到Vue.prototype
上,那说明**$router
是在Vue-Router内部挂载**的。
还有一个就是我们平时在任意组件中都可以使用<router-link>
和<router-view>
组件,而这并不是Vue自身的组件,说明Vue-Router还声明了两个全局组件。
所以这里可以转换成Vue-Router实现的起步需求就是实现一个Vue插件,该插件起步的功能有:
- 挂载
$rotuer
- 声明两个全局组件
router-link
和router-view
- 实现一个VueRouter类,实现hash模式下路由跳转
二、需求实现
先创建一个vue-router.js文件,在文件中创建一个VueRouter类
2.1 实现挂载$router
挂载$router
我们很容易想到在install方法去挂载,但这里有个问题,就是在执行install方法时,Vue还未实例化,这里并不能拿到router实例,Vue-Router的解析方法是在执行install方法时全局混入beforeCreate
生命周期方法,等这个生命周期方法执行时,Vue是已经实例化了,就可以拿到router实例了。
新建vue-router.js
class VueRouter {
}
// Vue插件需要声明一个install方法
VueRouter.install = function (Vue) {
// 全局混入beforeCreate生命周期方法
Vue.mixin({
beforeCreate() {
// 只要在Vue根实例中挂载,利用只有根实例选项上有router属性找到根实例
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
}
}
})
}
2.2 声明两个全局组件
首先,我们要清楚在hash模式下,<router-link>
和<router-view>
组件到底有什么用。
<router-link to="/about">About