以下面一段vue模板為例
v-test
v-test2
>
div>
以上的模板會被編譯成渲染函式
with
(this),
]})}
如何獲取到我們設定的指令的鉤子,入口函式為updatedirectives
, 用來獲取所有的新指令和舊指令集合。
function
updatedirectives
(oldvnode, vnode)
可以看到以上主要使用到了normalizedirectives$1
函式,這個函式就是獲取指令的核心方法
function
normalizedirectives$1
(dirs, name)
;var i, dir;
// 遍歷本節點的所有的指令,逐個從組建中獲取
for(i =
0; i < dirs.length; i++
)return res;
}
經過以上這一步的處理,我們的directives
會變成一下這個樣子
directives:[,
unbind()
}}]
上面一篇文章已經說過,bind, update, unbind都是直接觸發的。
下面主要來看inserted
和componentupdated
inserted是在dom插入父節點之後才觸發,而處理inserted是在dom插入之前,所以這裡不可能直接觸發,inserted分為儲存和執行兩個步驟
function
updatedirectives
(oldvnode, vnode)}}
if(dirswithinsert.length)};
// 合併到hook中的insert
if(iscreate)
else
}}
當頁面初始化時,呼叫patch處理根節點,開始插入頁面的步驟,其中會不斷遍歷子節點
function
patch
(oldvnode, vnode, hydrating, removeonly, parentelm, refelm)
// 不是更新,而是頁面初始化
else
return vnode.elm
}
上面的createelement會建立本節點以及其後代節點,然後插入到父節點中,等到createelm執行完,所有的節點都已經插入完畢了
function
createelm
(
vnode,insertedvnodequeue,
parentelm,refelm)}
// 處理本節點的事件,屬性等,其中包含對指令的處理
invokecreatehooks
(vnode, insertedvnodequeue)
;// 插入 本dom 到父節點中
insert
(parentelm, vnode.elm, refelm)
;}
整個createelm之後,會呼叫invokeinserthook,這就是呼叫insert的時機,我們可以看看invokeinserthook做了什麼
// 將之前儲存的insert鉤子一次性全部觸發
function
invokeinserthook
(vnode, insertedvnodequeue)
}
componentupdated
也是分為儲存和執行兩段原始碼
// 把指令componentupdated的函式 和本節點的 postpatch 合併起來
if(dirswithpostpatch.length)})
;}
componentupdated鉤子是更新乙個節點就馬上執行,更新乙個節點的意思是包括其內部子節點的,更新乙個節點也會呼叫patch
function
patch
(oldvnode, vnode)
return vnode.elm
}function
patchvnode
(oldvnode, vnode)
}
Vue中directive原理分析
vue在處理指令時,會首先判斷指令是新的還是舊的。也就是需要對比舊節點和新節點上的指令。比如新節點比舊節點上多了乙個指令。新節點上指令如下 newdirectives v test2 舊節點上指令如下 newdirectives 可以看到新節點上增加了乙個指令v test2,當我們遍歷發現v tes...
Vue封裝常用指令Directive
需求 只能輸入數字 輸入字母和特殊字元自動過濾掉 輸入完成失焦自動加.00 如果輸入了小數自動四捨五入為22.22類似這樣格式 將數值四捨五入後格式化.param num 數值 number或者string param cent 要保留的小數字 number param isthousand 是否需...
vue自定義指令directive
1 指令的使用 v dir1 v color red div type text v focus div 2 建立區域性指令 newvue 建立指令 可以多個 directives color 3 全域性指令,一般在main.js中定義 為繫結的元素自動獲取焦點 vue.directive focu...