Vue指令的鉤子函數(shù)使用方法
在Vue 中可以把一系列復雜的操作包裝為一個指令。
什么是復雜的操作?
我的理解是:復雜邏輯功能的包裝、違背數(shù)據(jù)驅(qū)動的 DOM 操作以及對一些 Hack 手段的掩蓋等。我們總是期望以操作數(shù)據(jù)的形式來實現(xiàn)功能邏輯。
鉤子函數(shù)
對于自定義指令的定義,Vue2 有 5 個可選的鉤子函數(shù)。
bind: 只調(diào)用一次,指令第一次綁定到元素時調(diào)用,用這個鉤子函數(shù)可以定義一個在綁定時執(zhí)行一次的初始化動作。
inserted: 被綁定元素插入父節(jié)點時調(diào)用(父節(jié)點存在即可調(diào)用,不必存在于 document 中)。
update: 被綁定元素所在的模板更新時調(diào)用,而不論綁定值是否變化。
componentUpdated: 被綁定元素所在模板完成一次更新周期時調(diào)用。
unbind: 只調(diào)用一次,指令與元素解綁時調(diào)用。
接下來,定義一個簡單的指令以驗證這些鉤子函數(shù)的觸發(fā)時機。
template
<div id="app"> <my-comp v-if="msg" :msg="msg"></my-comp> <button @click="update">更新</button> <button @click="uninstall">卸載</button> <button @click="install">安裝</button> </div>
script
Vue.directive('hello', { bind: function (el) { console.log('bind') }, inserted: function (el) { console.log('inserted') }, update: function (el) { console.log('update') }, componentUpdated: function (el) { console.log('componentUpdated') }, unbind: function (el) { console.log('unbind') } }) var myComp = { template: '<h1 v-hello>{{msg}}</h1>', props: { msg: String } } new Vue({ el: '#app', data: { msg: 'Hello' }, components: { myComp: myComp }, methods: { update: function () { this.msg = 'Hi' }, uninstall: function () { this.msg = '' }, install: function () { this.msg = 'Hello' } } })
頁面加載時
bind
inserted
組件更新時
點擊“更新”按鈕,更改數(shù)據(jù)觸發(fā)組件更新。
update
componentUpdated
卸載組件時
點擊“卸載”按鈕,數(shù)據(jù)置空否定判斷以觸發(fā)組件卸載。
unbind
重新安裝組件時
點擊“安裝”按鈕,數(shù)據(jù)賦值肯定判斷以觸發(fā)組件重新安裝。
bind
inserted
區(qū)別
從案例的運行中,對 5 個鉤子函數(shù)的觸發(fā)時機有了初步的認識。存疑的也就是bind和inserted、update和componentUpdated的區(qū)別了。
bind 和 inserted
據(jù)文檔所說,插入父節(jié)點時調(diào)用 inserted,來個測試。
bind: function (el) { console.log(el.parentNode) // null console.log('bind') }, inserted: function (el) { console.log(el.parentNode) // <div id="app">...</div> console.log('inserted') }
分別在兩個鉤子函數(shù)中輸出父節(jié)點:bind 時父節(jié)點為 null,inserted 時父節(jié)點存在。
update 和 componentUpdated
關于這兩個的介紹,從字眼上看感覺是組件更新周期有關,繼續(xù)驗證。
update: function (el) { console.log(el.innerHTML) // Hello console.log('update') }, componentUpdated: function (el) { console.log(el.innerHTML) // Hi console.log('componentUpdated') }
沒毛病,update 和 componentUpdated 就是組件更新前和更新后的區(qū)別。
結論
文檔說的沒錯……
Demo
最佳實踐
根據(jù)需求的不同,我們要選擇恰當?shù)臅r機去初始化指令、更新指令調(diào)用參數(shù)以及釋放指令存在時的內(nèi)存占用等。
比較常見的場景是:用指令包裝一些無依賴的第三方庫以擴展組件功能。而一個健壯的庫通常會包含:初始化實例、參數(shù)更新和釋放實例資源占用等操作。
Vue.directive('hello', { bind: function (el, binding) { // 在 bind 鉤子中初始化庫實例 // 如果需要使用父節(jié)點,也可以在 inserted 鉤子中執(zhí)行 el.__library__ = new Library(el, binding.value) }, update: function (el, binding) { // 模版更新意味著指令的參數(shù)可能被改變,這里可以對庫實例的參數(shù)作更新 // 酌情使用 update 或 componentUpdated 鉤子 el.__library__.setOptions(Object.assign(binding.oldValue, binding.value)) }, unbind: function (el) { // 釋放實例 el.__library__.destory() } })
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
js + css實現(xiàn)標簽內(nèi)容切換功能(實例講解)
下面小編就為大家?guī)硪黄猨s + css實現(xiàn)標簽內(nèi)容切換功能(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10深入理解事件冒泡(Bubble)和事件捕捉(capture)
下面小編就為大家?guī)硪黄钊肜斫馐录芭?Bubble)和事件捕捉(capture)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05