寫在前面
此系列來(lái)源于開源項(xiàng)目:前端 100 問(wèn):能搞懂 80%的請(qǐng)把簡(jiǎn)歷給我
為了備戰(zhàn) 2021 春招
每天一題斩箫,督促自己
從多方面多角度總結(jié)答案吏砂,豐富知識(shí)
vue 在 v-for 時(shí)給每項(xiàng)元素綁定事件需要用事件代理嗎撵儿?為什么?
簡(jiǎn)書整合地址:前端 100 問(wèn)
正文回答
首先我們需要知道事件代理主要有什么作用狐血?
- 事件代理能夠避免我們逐個(gè)的去給元素新增和刪除事件
- 事件代理比每一個(gè)元素都綁定一個(gè)事件性能要更好
事件代理作用主要是 2 個(gè)
- 將事件處理程序代理到父節(jié)點(diǎn)淀歇,減少內(nèi)存占用率
- 動(dòng)態(tài)生成子節(jié)點(diǎn)時(shí)能自動(dòng)綁定事件處理程序到父節(jié)點(diǎn)
這里我生成了十萬(wàn)個(gè) span
節(jié)點(diǎn),通過(guò) performance monitor 來(lái)監(jiān)控內(nèi)存占用率和事件監(jiān)聽器的數(shù)量匈织,對(duì)比以下 3 種情況
<!-- 1. 不使用事件代理浪默,每個(gè) span 節(jié)點(diǎn)綁定一個(gè) click 事件,并指向同一個(gè)事件處理程序 -->
<div>
<span v-for="(item,index) of 100000" :key="index" @click="handleClick">
{{item}}
</span>
</div>
<!-- 2. 不使用事件代理缀匕,每個(gè) span 節(jié)點(diǎn)綁定一個(gè) click 事件纳决,并指向不同的事件處理程序 -->
<div>
<span v-for="(item,index) of 100000" :key="index" @click="function () {}">
{{item}}
</span>
</div>
<!-- 3. 使用事件代理 -->
<div @click="handleClick">
<span v-for="(item,index) of 100000" :key="index"> {{item}} </span>
</div>
使用事件代理無(wú)論是監(jiān)聽器數(shù)量和內(nèi)存占用率都比前兩者要少
同時(shí)對(duì)比 3 個(gè)圖中監(jiān)聽器的數(shù)量以及我以往閱讀 vue 源碼的過(guò)程中,并沒(méi)有發(fā)現(xiàn) vue 會(huì)自動(dòng)做事件代理乡小,但是一般給 v-for
綁定事件時(shí)阔加,都會(huì)讓節(jié)點(diǎn)指向同一個(gè)事件處理程序(第二種情況可以運(yùn)行,但是 eslint 會(huì)警告)满钟,一定程度上比每生成一個(gè)節(jié)點(diǎn)都綁定一個(gè)不同的事件處理程序性能好胜榔,但是監(jiān)聽器的數(shù)量仍不會(huì)變,所以使用事件代理會(huì)更好一點(diǎn)
從 vue 的角度上來(lái)看上面兩點(diǎn)
- 在
v-for
中湃番,我們直接用一個(gè)for
循環(huán)就能在模板中將每個(gè)元素都綁定上事件苗分,并且當(dāng)組件銷毀時(shí),vue 也會(huì)自動(dòng)給我們將所有的事件處理器都移除掉牵辣。所以事件代理能做到的第一點(diǎn) vue 已經(jīng)給我們做到了 - 在
v-for
中摔癣,給元素綁定的都是相同的事件,所以除非上千行的元素需要加上事件纬向,其實(shí)和使用事件代理的性能差別不大择浊,所以也沒(méi)必要用事件代理