• Vue-Router 源码分析(三) VueRouter实例的属性和方法


    我们首先用new VueRouter()创建一个VueRouter实例,之后在创建根Vue实例时把这个VueRouter实例作为router属性传递进去,在这个过程中一般有两种方法可以获取到该VueRouter的实例

    第一种是node环境下,我们一般在项目源码的路劲下创建一个router目录,该目录保存所有的路由配置信息,例如:

    var router = new Router({
      routes: [/**/]
    })
    router.forEach((to,from,next)=>{
      next();
    })
    export default router;

    这里我们创建new Router实例后可以直接对该实例进行操作,比如这里通过VueRouter实例设置了forEach导航守卫

    还有一种获取VueRouter实例的地方是在vue内,我们可以通过this.$router获取到VueRouter实例:

    this.$router.push('/login')

    通过this.$router我们可以通过push、back等API进行路由跳转。对于VueRouter实例来说它含有如下属性和方法:

    • app          配置了router的Vue根实例
    • mode            当前的路由模式,可以为hash、history或者abstract
    • options         创建VueRouter实例时传入的所有参数
    • history          当前的History对象(通过该对象进行路由跳转的)
    • addRoutes   动态添加更多的路由规则,参数必须时一个符合routes选项要求的数组
    • push                      路由到新的路由地址
    • replace                 替换当前路由到新的路由(它不会向history添加新记录)
    • go                         在history记录中向前或向后退多少步
    • back                     在history记录中后退一步,等效于go(-1)
    • forward                 在history记录中前进一步,等效于go(1)
    • beforeEach                    全局前置守卫
    • beforeResolve              全局解析守卫
    • afterEach                      全局后置钩子
    • onReady(callback,errorCallback)    注册两个回调函数,在路由完成初始导航时触发
    • onError(callback)                  注册一个回调,该回调会在导航过程中出错时被调用

    对于app属性来说,我们经常用到的地方就是在导航首位里可以通过router.app.$store.tokens获取当前是否有tokens,如果没有,则路由到登录页面

    在vue组件内可以通过this.$router.push()等进行路由跳转,这些都是执行VueRouter实例的方法来实现的。

    在Vue源码内,VueRouter是一个函数对象,如下:

    var VueRouter = function VueRouter (options) {      //构造函数
      if ( options === void 0 ) options = {};             //如果option为undefined,则修正为空对象
    
      this.app = null;
      this.apps = [];
      this.options = options;                             //保存options
      this.beforeHooks = [];                              //初始化三个数组,分别对应beforeEach、beforeResolve、afterEach三个全局导航守卫的注册函数
      this.resolveHooks = [];
      this.afterHooks = [];
      this.matcher = createMatcher(options.routes || [], this);
    
      //初始化/修正mode
      var mode = options.mode || 'hash';
      this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false;
      if (this.fallback) {
        mode = 'hash';
      }
      if (!inBrowser) {
        mode = 'abstract';
      }
      this.mode = mode;
    
      switch (mode) {                                     //根据不同的模式,对this.history做出实例化
        case 'history':
          this.history = new HTML5History(this, options.base);
          break
        case 'hash':
          this.history = new HashHistory(this, options.base, this.fallback);
          break
        case 'abstract':
          this.history = new AbstractHistory(this, options.base);
          break
        default:
          {
            assert(false, ("invalid mode: " + mode));
          }
      }
    };

    其它的方法都是定义在VueRouter的原型对象上的,对于跳转的接口来说(push、replace、go、back、forward)来说,它们是操作this.history对象来实现跳转的。

    vue初始化时会在beforeCreate生命周期函数内会执行VuerRouter实例的init方法,如下:

    VueRouter.prototype.init = function init (app ) {     //路由初始化,在Vue实例的beforeCreate生命周期时执行 app:使用了该Vue-router的Vue实例,页面初始化时执行到这里
        var this$1 = this;                                    //this$1指向VueRouter实例
    
      "development" !== 'production' && assert(
        install.installed,
        "not installed. Make sure to call `Vue.use(VueRouter)` " +
        "before creating root instance."
      );
    
      this.apps.push(app);
    
      // main app already initialized.
      if (this.app) {
        return
      }
    
      this.app = app;                                         //设置this.app等于app,也就是Vue实例
    
      var history = this.history;                             //获取history实例
    
      if (history instanceof HTML5History) {                  //执行History.transitionTo()进行路由初始化,路由初始化完成后会触发onReady()注册的回调函数的。
        history.transitionTo(history.getCurrentLocation());
      } else if (history instanceof HashHistory) {            
        var setupHashListener = function () {
          history.setupListeners();
        };
        history.transitionTo(
          history.getCurrentLocation(),
          setupHashListener,
          setupHashListener
        );
      }
    
      history.listen(function (route) {
        this$1.apps.forEach(function (app) {
          app._route = route;
        });
      });
    };

    路由初始胡完成后就会等到<Vue-Link>触发相应的事件(默认为click)进行路由跳转了,或者通过push()、go()等函数式编程触发了。

  • 相关阅读:
    初始化操作由“case”标签跳过
    NI采集卡DO例程2 WriteDigChanExtClk
    QT中QString 类的使用获取指定字符位置、截取子字符串等
    NI采集卡DO例程1 WriteDigChan
    springboot链路追踪ID
    Java读取pem文件使用RSA加密解密
    docker安装logstash并读取syslog数据
    MySQL事务隔离级别
    Golang的RSA加密
    springboot整合log4j
  • 原文地址:https://www.cnblogs.com/greatdesert/p/12441907.html
Copyright © 2020-2023  润新知