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