vue-router

发布时间 2023-04-09 20:09:55作者: igoodful

###################

npm install vue-router

 

 

 

 

 

 

 Vue.use()方法的源代码如下:

function install(Vue) {
  // 避免重复安装插件
  if (install.installed && _Vue === Vue) return
  install.installed = true
  _Vue = Vue
  // 执行插件的安装方法
  const isDef = val => val !== 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() {
      // 如果有router选项,则把router挂在到vue实例上
      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)
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this, this)
    },
    destroyed() {
      registerInstance(this)
    },
  })
  // 注册router-link和router-view全局组件
  _Vue.component('RouterView', View)
  _Vue.component('RouterLink', Link)
  
  // 在Vue原型上定义$router和$route属性
  Object.defineProperty(Vue.prototype, '$router', {
    get() { return this._routerRoot._router }
  })
  Object.defineProperty(Vue.prototype, '$route', {
    get() { return this._routerRoot._route }
  })

  // 注册钩子函数,用于处理VueRouter的生命周期
  Vue.mixin({
    beforeRouteEnter(to, from, next) {
      next(vm => {
        if (!vm._isMounted) {
          // 如果Vue组件没有挂载,则在挂载时再执行beforeRouteEnter函数
          vm.$nextTick(() => {
            next(vm)
          })
        }
      })
    },
    beforeRouteUpdate(to, from, next) {
      const { matched } = this.$route
      const prevMatched = from.matched
      let diffed = false
      const activated = matched.filter((c, i) => {
        return diffed || (diffed = (prevMatched[i] !== c))
      })
      if (!activated.length) {
        this.$nextTick(() => {
          next()
        })
      } else {
        const queue = activated.map(c => {
          return new Promise((resolve, reject) => {
            if (c.beforeRouteEnter) {
              c.beforeRouteEnter(to, from, () => {
                resolve()
              })
            } else {
              resolve()
            }
          })
        })
        Promise.all(queue).then(() => {
          next()
        }).catch(() => {
          next(false)
        })
      }
    },
    beforeRouteLeave(to, from, next) {
      const matched = this.$route.matched
      const component = matched[matched.length - 1]
      if (!component || !component.beforeRouteLeave) {
        next()
      } else {
        component.beforeRouteLeave(to, from, () => {
          next()
        })
      }
    }
  })
}

export default {
  install,
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

##########################