vue的matcher_vue-router工作原理概述和问题分析
工作原理簡要流程圖
hashchange
-->
match route
-->
set vm._route
-->
render()
-->
render matched component
問題
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來做匹配。修改了matcher即新的routes生效。
match (
raw: RawLocation,
current?: Route,
redirectedFrom?: Location
): Route {
// 這里使用matcher的match方法來做匹配
return this.matcher.match(raw, current, redirectedFrom)
}
對router.matcher屬性做修改,即新的routes就會替換老的routes, 其實就是replaceRoutes()的含義(但是官方沒有提供這個API)。
export type Matcher = {
match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
addRoutes: (routes: Array) => void;
};
5. router-view是什么
組件是一個functional 組件,渲染路徑匹配到的視圖組件。 渲染的組件還可以內嵌自己的 ,根據嵌套路徑,渲染嵌套組件。
主要流程
初始化
實例化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://zhuanlan.zhihu.com/p/... 這篇文章講的也比較詳細,最好的是提供了自己造的vue-router的簡易版輪子,更方便大家理解,這個輪子很好。 【推薦閱讀輪子這一部分】
總結
以上是生活随笔為你收集整理的vue的matcher_vue-router工作原理概述和问题分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么刹车热了会失灵_网曝比亚迪汉“刹车
- 下一篇: 华为耳机5根线怎么接线图解_联通宽带突然