Vue-Router
是Vue.js
官方的路由管理器, 开发者可以自由选择是否使用Vue-Router
作为路由管理器, 因为它是作为Vue插件的形式被安装到Vue中的.
如何安装一个Vue插件
如果插件是一个对象, 必须提供
install
方法. 如果插件是一个函数, 它会被作为install方法. install方法调用时, 会将Vue作为参数传入. 该方法需要在调用new Vue()
之前被调用
当
install
方法被同一个插件多次调用, 插件将只会被安装一次
以上是官方文档的描述, 我们还是看代码吧
// 该方法会在initGlobalAPI初始化全局api的时候被执行export function initUse (Vue: GlobalAPI) { // 在Vue对象上添加use方法, 方法的参数可以是方法或者对象 Vue.use = function (plugin: Function | Object) { // 获取当前实例已经安装过插件列表 const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) // 判断是该插件是否已经被安装过 // 也就是文档描述的, 当同一个插件多次调用, 插件将只会被安装一次 if (installedPlugins.indexOf(plugin) > -1) { return this } // 额外的参数 const args = toArray(arguments, 1) // 把当前实例插入到参数数组的首位 args.unshift(this) if (typeof plugin.install === 'function') { // 这里判断plugin是否提供了install方法 // 调用plugin.install, 并传入额外的参数 plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { // 否则, 如果plugin是一个函数, 它会被作为install方法 // 把plugin作为install调用, 并传入额外的参数 plugin.apply(null, args) } // 把当前插件添加到已安装插件列表中 installedPlugins.push(plugin) return this }}复制代码
在代码中能更加清晰地了解到官方文档所描述的内容
Vue-Router的install
如果在一个模块化工程使用Vue-Router, 必须通过Vue.use()
明确地安装路由功能
import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)复制代码
而在VueRouter被定义的时候, 已经定义了VueRouter.install
供Vue.use(VueRouter)
执行其install
方法
既然都定义了VueRouter.install方法, 那就顺便看一下install过程VueRouter都干了什么吧
// 这个方法的第一个参数是Vue构造函数, 第二个参数是一个可选对象export function install (Vue) { // 确认install只会调用一次 if (install.installed && _Vue === Vue) return // 定义该插件已经被安装 install.installed = true // 把Vue赋值给全局变量 _Vue = Vue // 判断变量v是否不为undefined const isDef = v => v !== undefined const registerInstance = (vm, callVal) => { let i = vm.$options._parentVnode if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) { i(vm, callVal) } } // Vue.mixin 注入组件 Vue.mixin({ beforeCreate () { // 判断组件是否存在router对象, 该对象只在根组件上有 if (isDef(this.$options.router)) { // 根路由设置为自己 this._routerRoot = this this._router = this.$options.router // 调用VueRouter实例的init()方法, 初始化路由 this._router.init(this) // 为_route属性实现双向绑定 Vue.util.defineReactive(this, '_route', this._router.history.current) } else { // 用于router-view层级判断 this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } registerInstance(this, this) }, destroyed () { registerInstance(this) } }) // 定义Vue.$router的返回值 Object.defineProperty(Vue.prototype, '$router', { get () { return this._routerRoot._router } }) // 定义Vue.$route的返回值 Object.defineProperty(Vue.prototype, '$route', { get () { return this._routerRoot._route } }) // 全局注册组件router-view和router-link Vue.component('RouterView', View) Vue.component('RouterLink', Link) // 获取自定义选择合并策略 const strats = Vue.config.optionMergeStrategies // beforeRouteEnter, beforeRouteLeave, beforeRouteUpdate 与 created使用相同的合并策略 strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created}复制代码
以上就是Vue.use(VueRouter)的过程, 这也是为什么Vue-Router能被Vue使用的实现, 了解这些等于知道如何开始自己开发Vue插件了