美文网首页
Vue-router(3.1.6)源码阅读——路由的安装

Vue-router(3.1.6)源码阅读——路由的安装

作者: 李牧敲代码 | 来源:发表于2020-04-10 22:01 被阅读0次

    Vue提供了全局的use方法去安装插件,使用use后会自动执行插件里的intall方法来安装:

    /* @flow */
    
    import { toArray } from '../util/index'
    
    export function initUse (Vue: GlobalAPI) {
      Vue.use = function (plugin: Function | Object) {
        const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))//保存Vue上已经有的插件
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
    
        // additional parameters
        const args = toArray(arguments, 1)
    
        args.unshift(this)//让每个插件的第一个参数都能拿到Vue
        if (typeof plugin.install === 'function') {
          plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args)
        }
        installedPlugins.push(plugin)
        return this
      }
    }
    

    这就是use的所有源码,很简单,先保存一份Vue已有的插件,然后看下新安装的插件是否存在,存在则退出,否则判断插件的install方法是否是函数或者是本身是函数,是则调用,然后返回Vue.
    PS: 并且每个插件的install方法的第一个参数都能拿到vue

    再看vue-router的install定义:

    import View from './components/view'
    import Link from './components/link'
    
    export let _Vue
    
    export function install (Vue) {
      if (install.installed && _Vue === Vue) return
      install.installed = true//vue-router只安装一次
    
      _Vue = Vue
    
      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({
        beforeCreate () {
          if (isDef(this.$options.router)) {
            this._routerRoot = this
            this._router = this.$options.router
            this._router.init(this)
            Vue.util.defineReactive(this, '_route', this._router.history.current)//将_route变为响应式的
          } else {
            this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
          }
          registerInstance(this, this)
        },
        destroyed () {
          registerInstance(this)
        }
      })
    
      Object.defineProperty(Vue.prototype, '$router', {//这样每个vue实例都能访问了
        get () { return this._routerRoot._router }
      })
    
      Object.defineProperty(Vue.prototype, '$route', {
        get () { return this._routerRoot._route }
      })
    
      Vue.component('RouterView', View)//定义了<router-view>组件
      Vue.component('RouterLink', Link)//定义了<router-link>组件
    
      const strats = Vue.config.optionMergeStrategies
      // use the same hook merging strategy for route hooks
      strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created//对3个钩子都采用created的策略
    }
    

    可以看到这个install做了几件事:

    1. 将Vue保存给_Vue.免得每次都要import
    2. 通过Vue.mixin给每个组件入住beforeCreate和destroyed两个构造函数
    3. 通过Object.defineProperty师德我们能通过Vue.route和Vue.router访问route和router。
    4. 注册了<router-view>和<router-link>2个组件使得我们全局可以使用。

    总结:

    1. Vue提供了全局的use方法去安装插件,使用use后会自动执行插件里的intall方法来安装,并且每个插件的install方法的第一个参数都能拿到vue
    2. install方法将Vue保存给_Vue.免得每次都要import
    3. install方法通过Vue.mixin给每个组件入住beforeCreate和destroyed两个钩子函数
    4. install方法通过Object.defineProperty使得我们能通过Vue.$route和Vue.$router访问route和router。
    5. install方法注册了<router-view>和<router-link>2个组件使得我们全局可以使用。

    返回目录

    相关文章

      网友评论

          本文标题:Vue-router(3.1.6)源码阅读——路由的安装

          本文链接:https://www.haomeiwen.com/subject/uajdmhtx.html