詳解vue指令與$nextTick 操作DOM的不同之處
異步更新隊列
可能你還沒有注意到,Vue 異步執(zhí)行 DOM 更新。只要觀察到數(shù)據(jù)變化,Vue 將開啟一個隊列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)改變。如果同一個 watcher 被多次觸發(fā),只會被推入到隊列中一次。這種在緩沖時去除重復(fù)數(shù)據(jù)對于避免不必要的計算和 DOM 操作上非常重要。然后,在下一個的事件循環(huán)“tick”中,Vue 刷新隊列并執(zhí)行實際 (已去重的) 工作。Vue 在內(nèi)部嘗試對異步隊列使用原生的 Promise.then
和 MessageChannel
,如果執(zhí)行環(huán)境不支持,會采用 setTimeout(fn, 0) 代替。
例如,當(dāng)你設(shè)置 vm.someData = 'new value'
,該組件不會立即重新渲染。當(dāng)刷新隊列時,組件會在事件循環(huán)隊列清空時的下一個“tick”更新。多數(shù)情況我們不需要關(guān)心這個過程,但是如果你想在 DOM 狀態(tài)更新后做點什么,這就可能會有些棘手。雖然 Vue.js 通常鼓勵開發(fā)人員沿著“數(shù)據(jù)驅(qū)動”的方式思考,避免直接接觸 DOM,但是有時我們確實要這么做。為了在數(shù)據(jù)變化之后等待 Vue 完成更新 DOM ,可以在數(shù)據(jù)變化之后立即使用 Vue.nextTick(callback) 。這樣回調(diào)函數(shù)在 DOM 更新完成后就會調(diào)用。例如:
<div id="example">{{message}}</div> var vm = new Vue({ el: '#example', data: { message: '123' } }) vm.message = 'new message' // 更改數(shù)據(jù) vm.$el.textContent === 'new message' // false Vue.nextTick(function () { vm.$el.textContent === 'new message' // true })
在組件內(nèi)使用 vm.$nextTick()
實例方法特別方便,因為它不需要全局 Vue ,并且回調(diào)函數(shù)中的 this 將自動綁定到當(dāng)前的 Vue 實例上:
Vue.component('example', { template: '<span>{{ message }}</span>', data: function () { return { message: '沒有更新' } }, methods: { updateMessage: function () { this.message = '更新完成' console.log(this.$el.textContent) // => '沒有更新' this.$nextTick(function () { console.log(this.$el.textContent) // => '更新完成' }) } } })
vue指令
鉤子函數(shù)
一個指令定義對象可以提供如下幾個鉤子函數(shù) (均為可選):
bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。
inserted:被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)。
update:所在組件的 VNode 更新時調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見下)。
componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
unbind:只調(diào)用一次,指令與元素解綁時調(diào)用。
鉤子函數(shù)的參數(shù) (即 el、binding、vnode 和 oldVnode)。
需要注意的是:update時dom可能還沒有插入文檔,componentUpdated是DOM已經(jīng)插入文檔。并且所謂的“更新”這個鉤子函數(shù)的觸發(fā)條件非常寬泛,不容易把控。比如,其他與該節(jié)點無關(guān)的相鄰節(jié)點更新,引發(fā)其布局的重流,也會導(dǎo)致該鉤子函數(shù)觸發(fā)
因此,如果想要在數(shù)據(jù)更新后,操作DOM,使用指令的update, componentUpdated 需要謹(jǐn)慎,可以考慮使用nextTick
總結(jié)
以上所述是小編給大家介紹的vue指令與$nextTick 操作DOM的不同之處,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Vue3?封裝擴展并簡化Vuex在組件中的調(diào)用問題
這篇文章主要介紹了Vue3?封裝擴展并簡化Vuex在組件中的調(diào)用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01vue.js 解決v-model讓select默認(rèn)選中不生效的問題
這篇文章主要介紹了vue.js 解決v-model讓select默認(rèn)選中不生效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Vue項目通過node連接MySQL數(shù)據(jù)庫并實現(xiàn)增刪改查操作的過程詳解
最近在研究vue項目中使用node.js搭建server服務(wù)器,鏈接本地mysql數(shù)據(jù)庫,進(jìn)行數(shù)據(jù)操作,下面這篇文章主要給大家介紹了關(guān)于Vue項目通過node連接MySQL數(shù)據(jù)庫并實現(xiàn)增刪改查操作的相關(guān)資料,需要的朋友可以參考下2022-05-05Vue動態(tài)加載ECharts圖表數(shù)據(jù)的方式
這篇文章主要介紹了Vue動態(tài)加載ECharts圖表數(shù)據(jù)的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07