路由安装
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。ps: 因为是在定义在prototype,所以每个实例都能访问
5. install方法注册了<router-view>和<router-link>2个组件使得我们全局可以使用。
6. 通过Vue.util.defineReactive(this, '_route', this._router.history.current)使得路由是响应式的
路由模式
1. Html5History, HashHistory,Abstract三个模式类的实现大同小异,其核心都是通过transitionTo进行路由切换,前面两者部分用到浏览器的API,Abstract是通过数组模拟history记录栈.
2. Html5History,HashHistory都实现了监听浏览器url变化(可以参考浏览器的popstate和hashchangeAPI),Html5History监听‘popstate’,'HashHistory'先监听‘popstate’,没有相关API就监听‘hashchange’。
路由匹配
所以路由的匹配就是这样一条规则:
通过matcher的match方法(有name匹配name,没有就匹配path,然后返回,默认重新生成一条记录返回)解析用户的路由配置并按照route类型返回,然后路由切换就按照这个route来。
简单点的思路就是:
解析用户配置然后生成一个易于使用又包含所有信息的对象,根据这个对象来切换路由。
路由切换
路由切换都是在transitionTo做的,它做了如下几件事:
1. 根据path将record分成了updated(即将更新的),deactivated(即将失活的),activated (即将激活的)3组。
2. 将所有的钩子压入一个队列中,顺序为:
- beforerouteLeave(组件内的守卫)
- beforeEach(全局前置守卫)
- beforeRouteUpdate(组件内的守卫)
- beforeEnter(路由独享的守卫)
- 解析异步组件和同步组件
- beforeRouteEnter(组件内的守卫)
- beforeResolve(全局解析守卫)
- afterEach(全局后置钩子)
3. 判断异步组件的依据是其是否是函数。
4. beforeRouteEnter能在回调中拿到vm实例的原因是因为其中有个Poll方法一直在轮询,直到成功拿到vm并将vm作为参数传入回调函数中,因此我们能在回调函数中拿到vm。而beforeRouteEnter中的回调函数本身会在$nextTick中执行。
5. vue-router定义了一个“异步函数队列化执行的函数”,又定义了一个ITerator函数,只有我们调用了next方法,“异步函数队列化执行的函数”的步进器才会前进1步,才会执行我们的hook队列,这就是我们平常在hook中调用next的原因。
路由渲染
1. router-link是一个普通的组件,router-view是一个函数式组件。
2. router-link接受4个Props——to, tag,ariaCurrentValue, event。
3. router-link设置router-link激活和精确匹配的样式。
4. router-link根据tag来寻找a标签,并设置这个a标签的的一系列属性,找不到a标签,则把监听器全部绑定到router-link自身。
5. router-link创建了一个守卫函数, 通过守卫函数的由handler处理(根据this.replace决定用replace还是push)
6. 定义了注册路由实例的方法,这个方法会在init的时候执行。
7. 创建了一个depth标志位根据data.routerView遍历确定每个router-view层级。然后获得对应的component,进而进行渲染。
网友评论