這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

vm.$forceUpdate
(1)作用
迫使Vue.js實體重新渲染,注意它僅僅影響實體本身以及插入插槽內容的子組件,而不是所有子組件,
(2)實作
只需要執行watcher的update方法,就可以讓實體重新渲染,
Vue.js的每一個實體都有一個watcher,當狀態發生改變時,會通知到組件級別,然后組件內部使用虛擬DOM進行更詳細的重新渲染操作,
事實上,組件就是Vue.js實體,所以組件幾倍的watcher和Vue.js實體上的watcher說的是同一個watcher,
手動執行實體watcher的update方法,就可以使Vue.js實體重新渲染,
Vue.prototype.$forceUpdate = function(){
const vm = this;
if(vm._watcher){
vm._watcher.update();
}
}
vm._watcher就是Vue.js實體的watcher,每當組件內依賴的資料發生變化時,都會自動觸發Vue.js實體中_watcher的update方法,
重新渲染的實作原理并不難,Vue.js的自動渲染通過變化偵測來偵測資料,即當資料發生變化時,Vue.js實體重新渲染,而vm.$forceUpdate是手動通知Vue.js實體重新渲染,
vm.$destroy
(1)作用
完全銷毀一個實體,它會清理該實體與其他實體的連接,并解綁其全部指令及監聽器,同時會觸發beforeDestory和destroyed的鉤子函式,
(2)這個方法并不是很常用,大部分場景下并不需要銷毀組件,只需要使用v-if或則v-for等指令以資料驅動的方式控制子組件的生命周期即可,
(3)實作原理
Vue.prototype.$destory = function(){
const vm = this;
if(vm._isBeingDestroyed){
return;
}
callHook(vm,"beforeDestroy");
vm._isBeingDestroyed = = true;
}
1、為了防止vm.$destroy被反復執行,先對屬性_isBeingDestroyed進行判斷,如果它為true,說明Vue.js實體正在被銷毀,直接使用return陳述句退出函式執行邏輯,因為銷毀只需要銷毀一次即可,不需要反復銷毀,
2、然后呼叫callHook函式觸發beforeDestroy的鉤子函式(callHook會觸發引數中提供的鉤子函式),
(4)銷毀實體的邏輯1 首先,需要清理當前組件與父組件之間的連接,組件就是Vue.js實體,所以要清理當前組件與父組件之間的連接,只需要將當前組件實體從父組件實體的$children屬性中洗掉即可,
說明:Vue.js實體的$children屬性存盤了所有子組件
const parent = vm.$parent;
if(parent && !parent._isBeingDestroyed && !vm.$options.abstract){
remove(parent.$children,vm)
}
1、如果當前實體有父級,同時父級沒有被銷毀且不是抽象組件,那么將自己從父級的子串列中洗掉,也就是將自己的實體從父級的$children屬性中洗掉,
2、事實上,子組件在不同父組件中是不同的Vue.js實體,所以一個子組件實體的父級只有一個,銷毀操作也只需要從父級的子組件串列中銷毀當前這個Vue.js實體,
export function remove(arr,item){
if(arr.length){
const index = arr.indexOf(item);
if(index>-1){
return arr.splice(index,1);
}
}
}
(5)銷毀實體的邏輯2
1、父子組件間的鏈接斷掉之后,需要銷毀實體上的所有watcher,也就是說需要將實體上所有的依賴追蹤斷掉,
2、狀態會收集一些依賴,當狀態發生改變時會向這些依賴發送通知,而被收集的依賴就是watcher實體,因此,當Vue.js實體被銷毀時,應該將實體所監聽的狀態都取消掉,也就是從狀態的依賴串列中將watcher移除,
3、watcher的teardown方法,它的作用是從所有依賴項的Dep串列中將自己移除,即只要執行這個方法,就可以斷掉這個watcher所監聽的所有狀態,
4、斷掉Vue.js實體自身的watcher實體監聽的所有狀態,
if(vm._watcher){
vm._watcher.teardown();
}
5、執行了組件自身的watcher實體的teardown方法,從所有依賴項的訂閱串列中洗掉watcher實體,洗掉之后,當狀態發生變化時,watcher實體就不會再得到通知,
6、vm._watcher來源
當執行new Vue()時,會執行一系列初始化操作并渲染組件到物體上,其中就包括vm._watcher的處理
7、從Vue.js2.0開始,變化偵測的粒度調整為中等粒度,它只會發送通知到組件級別,然后組件使用虛擬DOM進行重新渲染,組件其實就是Vue.js實體,
8、怎么通知到組件級別
在Vue.js實體上,有一個watcher,也就是vm._watcher,它會監聽這個組件中用到的所有狀態,即這個組件內用到的所有狀態的依賴串列中都會收集到vm._watcher,當這些狀態發生變化時,也都會通知vm._watcher,然后這個watcher再呼叫虛擬DOM進行重新渲染,
(6)銷毀實體的邏輯
1、只從狀態的依賴串列中洗掉Vue.js實體上的watcher實體是不夠的,Vue.js提供了vm.watch所創建的watcher實體,
2、從狀態的依賴串列中銷毀用戶創建的watcher實體和銷毀Vue實體上的watcher實體相同,只需要執行watcher的teardown方法,
3、問題:如何知道用戶創建了多少個watcher?
1)Vue.js的解決方案是執行new Vue()時,在初始化的流程中,在this上添加一個_watchers屬性
vm._watchers = [];
2)每當創建watcher實體時,都會將watcher實體添加到vm._watchers中
export default class Watcher{
constructor(vm,expOrFn,cb){
<!-- 每當創建watcher實體時,都將watcher實體添加到vm._watchers中 -->
vm._watchers.push(this);
}
}
4、只需要遍歷vm._watchers并依次執行每一項watcher實體的teardown方法,就可以將watcher實體從它所監聽的狀態的依賴串列中移除,
let i = vm._watchers.length;
while(i--){
vm._watchers[i].teardown();
}
(7)向Vue.js實體添加_isDestroyed屬性來表示Vue.js實體已經被銷毀,
vm._isDestroyed = true;
(8)當vm.$destroy執行時,Vue.js不會將已經渲染到頁面中的DOM節點移除,但會將模板中的所有指令解綁,
vm._patch_(vm._vnode,null)
(9)觸發destroyed鉤子函式
callHook(vm,'destroyed')
(10)最后,移除實體上的所有事件監聽器,
vm.$off()
(11)完整代碼
Vue.prototype.$destory = function(){
const vm = this;
<!-- 防止重復銷毀 -->
if(vm._isBeingDestroyed){
return;
}
<!-- 呼叫鉤子函式beforeDestroy -->
callHook(vm,"beforeDestroy");
vm._isBeingDestroyed = = true;
<!-- 洗掉自己與父級之間的連接 -->
const parent = vm.$parent;
if(parent && !parent._isBeingDestroyed && !vm.$options.abstract){
remove(parent.$children,vm);
}
<!-- 從watcher監聽的所有狀態的依賴串列中移除watcher -->
if(vm._watcher){
vm._watcher.teardown();
}
let i = vm._watchers.length;
<!-- 將從vm.$watcher創建的watcher實體從它所監聽的狀態的依賴串列中移除 -->
while(i--){
vm._watchers[i].teardown();
}
<!-- 表示實體已經被銷毀 -->
vm._isDestroyed = true;
<!-- 將模板中的所有指令解綁 -->
vm._patch_(vm._vnode,null)
<!-- 觸發destroyed鉤子函式 -->
callHook(vm,'destroyed')
<!-- 移除實體上的所有事件監聽器 -->
vm.$off();
}
本文轉載于:
https://juejin.cn/post/6844904196840357902
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533552.html
標籤:其他
