通过vue-router学习vue

vue-router是vue官方支持,可以看做vue最佳实践
本文大致梳理vue-router源码各个文件大体作用,不深入细节
建议对照vue-router源码阅读

src/index.js

1. VueRouter类

  • 构造器

    • createMatcher分析路由配置、路径、层级等;
    • 根据modefallback配置和浏览器history.pushState支持情况创建对应的history实例(pushreplacego等方法,通过操作history实现);
  • init方法
  • 暴露addRoutespushreplacego等路由操作方法;
  • 暴露beforeEachbeforeResolveonReady等钩子函数;

2. VueRouter类添加install方法

这个方法的第一个参数是 Vue构造器,第二个参数是一个可选的选项对象(Vue插件);

src/install.js

VueRouter类的install方法

  • 判断Vue是否已初始化Vue-router;
  • 通过全局混入Vue.mixin实现注册和销毁,使用全局混入将影响每一个之后创建的 Vue 实例(Vue全局混入))。

    • beforeCreatethis指向为Vue组件实例,所有组件beforeCreate声明周期都会调用此函数;
    • this.$options.routernew Vue时传入的Vue-router实例,this.$options.router不为空,说明此时this指向Vue根组件实例;
    new Vue({
      router,// this.$options.router不为空,说明此时this指向Vue根组件实例
      render: h => h(App)
    }).$mount('#app')
    • this._routerRoot指向Vue根组件实例,后续所有子组件实例的_routerRoot均指向this.$parent._routerRoot,所有子组件的_routerRoot通过层层传递的形式指向根组件实例;
  • 添加 Vue实例属性$router$route,通过把它们添加到 Vue.prototype上实现。这里通过Object.defineProperty只设置了get方法,是为了防修改。这样所有组件可通过this.$routerthis.$route操作路由和获取当前路由信息。
  • 声明全局组件RouterViewRouterLink
  • 设置选项合并策略(自定义选项合并策略))

src/history/base.js

History类,HashHistoryHTML5History都继承自这个基础类

  • 定义go、push、replace、ensureURL、getCurrentLocation方法,由子类实现
  • 构造器,初始化属性,处理<base>标签

src/components/link.js

全局组件RouterLink

默认渲染为<a>标签

tag: {
    type: String,
    default: 'a'
}

默认事件为click

事件回调handler先通过guardEvent过滤掉部分事件,然后进行跳转

const handler = e => {
  if (guardEvent(e)) {
    if (this.replace) {
        router.replace(location, noop)
    } else {
        router.push(location, noop)
    }
  }
}

tag属性为a,则事件直接绑定到组件上

if (this.tag === 'a') {
  data.on = on
}

修改tag,则先查找default插槽(Vue具名插槽))中是否有<a>标签,有则绑定到最先找到的<a>标签上,没有找到则直接绑定到组件上

if (this.tag === 'a') {
    ...
} else {
    // find the first <a> child and apply listener and href
    const a = findAnchor(this.$slots.default)
    if (a) {
        // append new listeners for router-link
        ...
    } else {
        // doesn't have <a> child, apply listener to self
        data.on = on
    }
}

src/components/view.js

全局组件RouterViewfunctional组件(Vue函数式组件))

原文链接:segmentfault.com

上一篇:【JavaScript】for 循环 label 语句
下一篇:Node.js入门

相关推荐

官方社区

扫码加入 JavaScript 社区