Vue mounted異步,為什么watch 數據並nextTick


<template>
 <div class="swiper-slide" v-for="(carousel, index) in bannerList" :key="carousel.id" >
 <img :src="carousel.imgUrl" alt="" />
 </div>
</template>

mounted() {
 this.$store.dispatch('getBannerList');
},

watch: {
 bannerList(newvalue, oldvalue) {
	 this.$nextTick(() => {
 		var mySwiper = new Swiper(this.$refs.cur, {...}
	}
}

1 生命周期

渲染: 將內存中的模板,真實的掛載到了頁面中,讓用戶已經可以看到生成的DOM頁面
image

Vue 的生命周期總共分為8個階段:創建前/后,載入前/后,更新前/后,銷毀前/后。

1、beforeCreate(創建前)
表示實例完全被創建出來之前,vue 實例的掛載元素$el和數據對象 data 都為 undefined,還未初始化。

*2、created(創建后)
數據對象 data props已存在,可以調用computed methods 中的方法,操作 data 中的數據,但 dom 未生成,$el 未存在 。

*3、beforeMount(掛載前)
模板已經在內存中編輯完成了,vue 實例的 $el,掛載之前為虛擬的 dom節點,但是尚未把模板渲染到頁面中。data.message 未替換。

*4、mounted(掛載后)
vue 實例掛載完成,data.message 成功渲染。內存中的模板,已經真實的掛載到了頁面中,用戶已經可以看到渲染好的頁面了。實例創建期間的最后一個生命周期函數,當執行完 mounted 就表示,實例已經被完全創建好了,DOM 渲染在 mounted 中就已經完成了。

5、beforeUpdate(更新前)
當 data 變化時,會觸發beforeUpdate方法 。data 數據尚未和最新的數據保持同步。

6、updated(更新后)
當 data 變化時,會觸發 updated 方法。頁面和 data 數據已經保持同步了。

7、beforeDestory(銷毀前)
組件銷毀之前調用 ,在這一步,實例仍然完全可用。

8、destoryed(銷毀后)
組件銷毀之后調用,對 data 的改變不會再觸發周期函數,vue 實例已解除事件監聽和 dom綁定,但 dom 結構依然存在。
image

2 編譯compile

created()=>compile()=>beforemount()=>掛載並首次渲染=>mounted()
=>有數據變化優先updated(), 沒有則執行異步函數dispatch()

簡單來說, 就是將v-if v-for等解析出來, 本質上是if(){document....} for(){document.....}
因為是異步操作,dispatch不論是寫在created, 還是mounted里, 在進行編譯時都得不到v-for的數據
比如:
if(數據undefined, 即false){ document.getElementById(id).setAttribute(display=block) }
for(數據undefined 即false){ document.createElement() }
得到的是"錯誤"的DOM, 經過mounted第一次渲染, 得不到我們期望的頁面

我們想要var mySwiper = new Swiper(this.$refs.cur, {...}操作, 必須要等到頁面"正確"之后進行.
即: dispatch數據要回來(監視), 頁面要渲染完成(nexttick)

問題是, 這段js代碼寫在哪里?
寫在updated里是可以的(由生命周期圖可知), 但寫在watch里更好(由下圖可知)
watcher是watch的實例, 寫在watch里定位更精確

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM