title: Vue渲染父子組件時需要注意的點(diǎn)
date: 2018-11-19 18:55:58
tags: [Vue]
categories: Vue
前言
我在邊學(xué) Vue 邊做 轱轆UI 的項(xiàng)目中泥技,寫 row 組件 的測試用例時碰到了一個問題。
測試用例需要渲染兩個組件派继,它們是父子關(guān)系,但測試下來子組件并沒有拿到父組件的 gutter 屬性陵霉,發(fā)現(xiàn)原來是因?yàn)?Vue 異步的渲染囤热。
之后通過 setTimeout 和 done() 解決了這一問題鹊碍,之后便有了這篇博客。
分析
Vue到底是怎樣渲染組件到頁面的胡桃?看例子來分析吧
我們自己會怎么寫:
// 這是個同步的過程
var div = document.createElement('div')
document.body.appendChild(div)
而 Vue 不是這么簡單的:
var div = document.createElement('div')
var child = document.createElement('div')
// 步驟一踩叭,會觸發(fā)child的mounted事件,這是異步的
div.appendChild(child)
// 步驟二翠胰,會觸發(fā)div的mounted事件容贝,這也是異步的
document.body.appendChild(div)
// 步驟三,這行代碼會先于上面兩行執(zhí)行之景,因?yàn)檫@是同步的嗤疯,而此時div里還沒有child
console.log(div.outerHTML)
執(zhí)行順序:步驟三 → 步驟一 → 步驟二
Vue 鉤子的調(diào)用并不是同步的。
假如是同步的闺兢,mounted你寫了幾百行代碼茂缚,則需要大量的運(yùn)算,那Vue豈不是要等你執(zhí)行完再繼續(xù)屋谭?
所以 Vue 不應(yīng)該等脚囊,Vue 應(yīng)該優(yōu)先完成元素的渲染,這是一個異步的觸發(fā)
解決
我預(yù)想子組件會通過 mounted 鉤子拿到父組件傳來的 gutter 屬性桐磁,但我的測試用例執(zhí)行時悔耘,實(shí)際上還沒有執(zhí)行 mounted 鉤子,所以子組件才沒有拿到這個 gutter 屬性的值我擂。
知道了原因衬以,那么就好解決了,用 setTimeout(){}
另外由于測試框架默認(rèn)都是同步的代碼(這是測試框架的一個約定)校摩,所以要在參數(shù)中加上 done 看峻,在我的測試用例執(zhí)行完時調(diào)用 done()。
這樣衙吩,就解決了互妓。具體代碼可在此點(diǎn)擊 。