vue如何解決watch和methods值執(zhí)行順序問(wèn)題
問(wèn)題
- 父組件:
<GroupTransform :is-show.sync="selectPeopleDialogVisible" @callback="getSelectedPeople" ></GroupTransform>
watch: { selectGroupRight: { handler(val) { }, deep: true, }, }, methods:{ getSelectedPeople(){}, }
- 子組件:
confirm() { this.$emit('input', this.rightGroups); this.$emit('callback'); },
目的是當(dāng)我們觸發(fā)子組件的confirm時(shí),先更新該組件綁定的v-model的值觸發(fā)watch,然后再觸發(fā)callback事件綁定的方法getSelectedPeople。
但是實(shí)際執(zhí)行結(jié)果是先執(zhí)行了getSelectedPeople,然后再進(jìn)入了watch。
原因
查詢資料后得到以下結(jié)論,具體源碼和機(jī)制暫時(shí)不明
(1)頁(yè)面初始化時(shí): 會(huì)執(zhí)行一次computed,watch初始化時(shí)不會(huì)執(zhí)行,methods只有調(diào)用的時(shí)候才會(huì)執(zhí)行
(2)渲染完成后:
- 如果不是由點(diǎn)擊事件造成的數(shù)據(jù)變化,執(zhí)行順序?yàn)椋簑atch——beforeUpdate——computed——updated
- 如果是由點(diǎn)擊事件造成的數(shù)據(jù)變化,執(zhí)行順序?yàn)椋簃ethods——watch——beforeUpdate——computed——update
繼續(xù)深究:為什么watcher沒(méi)有立即執(zhí)行?
在vue的watcher.js文件源碼中,我找到了這么一段
// options if (options) { this.deep = !!options.deep this.user = !!options.user this.lazy = !!options.lazy this.sync = !!options.sync } else { this.deep = this.user = this.lazy = this.sync = false } ...... /** * Subscriber interface. * Will be called when a dependency changes. */ update () { /* istanbul ignore else */ if (this.lazy) { this.dirty = true } else if (this.sync) { this.run() } else { queueWatcher(this) } }
可以看到vue的watcher除了我們常用的deep屬性可以配置,其實(shí)還有一個(gè)屬性叫做sync,這個(gè)屬性影響著我們的watcher什么時(shí)候執(zhí)行watcher的回調(diào)。
正常情況下不設(shè)置sync,依賴數(shù)據(jù)變動(dòng)時(shí)會(huì)觸發(fā)warcher將其推送進(jìn)入隊(duì)列,等到下一個(gè)渲染周期的時(shí)候觸發(fā)。
但是$emit觸發(fā)父組件的自定義事件不會(huì)等到下一個(gè)周期執(zhí)行,而是立即執(zhí)行。
所以代碼的效果就變成了先執(zhí)行callback綁定的父組件getSelectedPeople,再進(jìn)入watch。
解決方法
如果要程序按照我們最初的想法,先觸發(fā)watch,在執(zhí)行methods中的方法,那么只需要在watch中設(shè)置sync屬性為true即可。
watch: { selectGroupRight: { handler(val) {}, deep: true, sync: true, }, },
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于對(duì)keep-alive的理解,使用場(chǎng)景以及存在的問(wèn)題解讀
這篇文章主要介紹了關(guān)于對(duì)keep-alive的理解,使用場(chǎng)景以及存在的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05一篇文章搞懂Vue3中如何使用ref獲取元素節(jié)點(diǎn)
過(guò)去在Vue2中,我們采用ref來(lái)獲取標(biāo)簽的信息,用以替代傳統(tǒng) js 中的 DOM 行為,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章搞懂Vue3中如何使用ref獲取元素節(jié)點(diǎn)的相關(guān)資料,需要的朋友可以參考下2022-11-11vue動(dòng)畫—通過(guò)鉤子函數(shù)實(shí)現(xiàn)半場(chǎng)動(dòng)畫操作
這篇文章主要介紹了vue動(dòng)畫—通過(guò)鉤子函數(shù)實(shí)現(xiàn)半場(chǎng)動(dòng)畫操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08微信小程序Webview與H5通信的思路與實(shí)戰(zhàn)記錄
這篇文章主要介紹了微信小程序Webview與H5通信的思路與實(shí)戰(zhàn)的相關(guān)資料,由于微信小程序與H5之間的通信限制,無(wú)法滿足業(yè)務(wù)需求,通過(guò)動(dòng)態(tài)改變url的hash值來(lái)傳遞參數(shù),并利用vue-router組件的路由守衛(wèi)來(lái)避免頁(yè)面刷新,需要的朋友可以參考下2025-01-01vue實(shí)現(xiàn)循環(huán)滾動(dòng)圖片
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)循環(huán)滾動(dòng)圖片,多圖片輪播,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07