内容简介:在挂载router-view组件时,会生成一个watcher, router-view的render函数中又触发了_route的getter方法,那么此watcher就被收集到_route的Dep中了。在_route的setter触发时,自然执行了这个watcher, 组件重新render。
问题
1. 为什么url变更时,router-view组件就能渲染出在routes中定义的与当前path匹配的组件?
-
root vue实例上定义了一个响应式属性
Vue.util.defineReactive(this, '_route', this._router.history.current)
-
url变更时,会匹配到最新的route,并且会设置
this._routerRoot._route
, 触发setter
-
router-view组件的render函数中有使用到
parent.$route
, 也就是间接的触发了this._routerRoot._route
的getter
。 -
则
this._routerRoot._route
的setter
触发时即会触发router-view
的渲染watcher
, 再次渲染, 并且此时拿到的路由组件也是最新的。
本质上利用了vue的响应式属性,在route属性变更和router-view视图渲染之间建立关系。
route变更 => render重新渲染
2. router-view render中使用到 parent.$route
为什么就会被 this._routerRoot._route
收集watcher
在挂载router-view组件时,会生成一个watcher, router-view的render函数中又触发了_route的getter方法,那么此watcher就被收集到_route的Dep中了。
在_route的setter触发时,自然执行了这个watcher, 组件重新render。
在 vue的仓库中 vue/src/core/instance/lifecycle.js
中 mountComponent
方法中,能看到挂载组件时是会生成一个 watcher
的:
export function mountComponent( vm: Component, el: ?Element, hydrating?: boolean ) { ... let updateComponent updateComponent = () => { vm._update(vm._render(), hydrating) } new Watcher(vm, updateComponent, noop, { before() { ... } }) ... return vm }
3. this.$router, this.$route是怎么挂载每个vue组件上的?
Object.defineProperty(Vue.prototype, '$router', { get () { return this._routerRoot._router } }) Object.defineProperty(Vue.prototype, '$route', { get () { return this._routerRoot._route } })
4.替换routes的写法(这样写为什么有用)
// 替换现有router的routes router.matcher = new VueRouter({ routes: newRoutes }).matcher
router.matcher是比较核心的一个属性。对外提供两个方法match(负责route匹配), addRoutes(动态添加路由)。
具体原因:在做路径切换 transitionTo
方法中,首先就会使用 const route = this.router.match(location, this.current)
来匹配route, 其实内部会使用matcher来做匹配。修改了watcher即新的routes生效。
对router.matcher属性做修改,即新的routes就会替换老的routes, 其实就是 replaceRoutes()
的含义。
export type Matcher = { match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route; addRoutes: (routes: Array<RouteConfig>) => void; };
5. router-view是什么
<router-view> 组件是一个functional 组件,渲染路径匹配到的视图组件。<router-view> 渲染的组件还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。
<transition> <keep-alive> <router-view></router-view> </keep-alive> </transition>
工作原理简要流程图
hashchange --> match route --> set vm._route --> <router-view> render() --> render matched component
主要流程
-
初始化
- 实例化Router, options作为属性,根据mode生成HTML5History实例,或HashHistory实例
- 数据劫持,this.router.route =》 this.history.current
- 数据劫持,this.history.current.route变化时,自动执行render。
- 立即执行一次路由跳转(渲染路由组件)
-
路由监听
- HashHistory监听hashChange事件,HTML5History监听popstate事件
-
路由变化处理
-
两种方式触发路由变化
- a标签href方法(url先变化,会触发两个history监听的hashChange或popstate事件,然后进入路由变化处理)
- 调用router的push, replace, go方法(先进入路由变化处理,然后修改url)
-
路由变化具体处理过程
- history.transitionTo(根据path匹配到相应的route, 然后调度执行hooks, 然后更新this.current属性,触发视图更新)
- history.confirmTransition(调度执行上一个route和下一个route的相关生命周期hooks)
-
-
router的辅助API
- push(先进行路由变化处理,在更新url,使用history.pushState)
- replace() 和push处理方式一致, 只是更新url使用history.replaceState
- go 使用history.go方法
参考链接
https://cnodejs.org/topic/58d...
https://zhuanlan.zhihu.com/p/...
https://ustbhuangyi.github.io... 【这个比较详细,但是废话太多,看不清重点】
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- AOP概述及实现原理
- MySQL 主从基于 GTID 复制原理概述
- MySQL 主从基于position复制原理概述
- Qt Inside 之信号和槽原理概述
- 【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述
- 服务端指南 服务端概述 | 微服务架构概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构与算法分析
维斯 / 人民邮电 / 2006-10 / 59.00元
《数据结构与算法分析:C++描述》秉承Weiss著全一贯的严谨风格,同时又突出了实践。书中充分应用了现代C++语言特性,透彻地讲述了数据结构的原理和应用,不仅使学生具备算法分析能力,能够开发高效的程序,而且让学生掌握良好的程序设计技巧。一起来看看 《数据结构与算法分析》 这本书的介绍吧!