前端模拟面试练习提升题

实际上调用了VueRouter的install方法,对Vue进行了扩展,vueRouter的install方法如下:

function install (Vue) {

//如果已经挂载了,跳过

  if (install.installed && _Vue === Vue) { return }

//如果未挂载过, installed属性改为true

  install.installed = true;

//获取当前vue

  _Vue = Vue;


  var isDef = function (v) { return v !== undefined; };


  var registerInstance = function (vm, callVal) {

    var i = vm.$options._parentVnode;

    if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {

      i(vm, callVal);

    }

  };

//在vue的beforeCreate钩子和destroyed钩子中新增关于路由的处理

  Vue.mixin({

    beforeCreate: function beforeCreate () {

      if (isDef(this.$options.router)) {

        this._routerRoot = this;

        this._router = this.$options.router; //new VueRouter()

        this._router.init(this); //如果Vue实例参数中,有指定的router属性,执行init初始化

//调用vue.util里的方法,通过get和set劫持this._route,router-view实时更新

        Vue.util.defineReactive(this, '_route', this._router.history.current);

      } else {

        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;

      }

      registerInstance(this, this);

    },

    destroyed: function destroyed () {

      registerInstance(this);

    }

  });

//给vue新增$router, $route属性,并指定get方法返回值,$route属性。于是就有了,this.$router和this.$route对象可以使用。

  Object.defineProperty(Vue.prototype, '$router', {

//this._routerRoot => this (即vue)

//this._router =>new VueRouter()

    get: function get () { return this._routerRoot._router }

  });


  Object.defineProperty(Vue.prototype, '$route', {

    get: function get () { return this._routerRoot._route }

  });

//新增子组件RouterView, RouterLink

  Vue.component('RouterView', View);

  Vue.component('RouterLink', Link);


  var strats = Vue.config.optionMergeStrategies;

  // 默认一下组件内导航钩子跟created方法一样

  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;

}

对于配置了路由的vue实例,ins

 

 
————————————————