今天寫着寫着,忽然發現控制檯裏有錯誤:html
[Vue warn]: You may have an infinite update loop in a component render function
這個問題很奇怪,以前歷來沒有遇到過。若是是我本身主導的項目,倒也好辦,慢慢 debug 就是;恰恰在公司的項目裏遇到這個問題,而公司項目的體系結構很複雜,我還沒徹底掌握。更惱火的是,由於體系複雜,debug 也很是困難,再加上尚無測試框架,這個難搞啊……vue
好死不死的,當時是下午三、4點鐘,正好到了肚餓的時刻,結果又落入低血糖狀態,真是屋漏偏逢連陰雨,船小又碰頂頭風,餓得我腦仁生疼……面試
不過終於仍是被我 Google + debug 出來。事實上是這樣的,在 v-for
循環當中,若是用方法或者計算屬性對 vm.$data 的屬性進行操做,理論上,可能由於修改到循環對象,誘發無限循環。此時 Vue 就會發出警告(並非真的已經無限循環了)。segmentfault
例如這樣一個組件,它裏面是用 :checked + <label>
實現的一組按鈕。它有如下功能:框架
name
屬性<label>
控制 <input>
,須要給 <input>
設置 id
因而我選擇這樣作:函數
<template> <div> <template v-for="(item, index) in items"> <input type="checkbox" :name="'my-component-' + selfIndex" :id="getID"> <label :for="getID(false)"> <button type="button" @click="remove(index)">×</button> </template> </div> </template> <script> let count = 0; export default { data() { return { selfIndex: 0, itemIndex: 0, } }, methods: { getID(increase = true) { // 注意,問題就出在這裏 if (increase) { this.itemIndex++; } return `my-component-${this.selfIndex}-${this.itemIndex}`; }, }, beforeMount() { this.selfIndex = count; count++; } } </script>
這裏,爲了能生成惟一 ID,我選擇每次循環都對 vm.itemIndex++
,這就會出現前面說的問題,存在隱患。oop
解決的方案有兩種,一種是把 itemIndex
也放在局部變量裏,使它不直接關聯在組件上;另外一種則是寫一個全局的惟一 ID 生成函數,而後引用進來。原理都是同樣的。重複的部分就不寫了,修改後大致以下:學習
<script> let count = 0; let itemCount = 0; // 把元素計數器放在這裏 export default { methods: { getID(increase = true) { if (increase) { itemCount++; } return `my-component-${this.selfIndex}-${itemCount}`; } } }; </script>
// helper.js 生成惟一 id let count = 0; export default function uniqueID(increase = true) { if (increase) { count++; } return `prefix-${count}`; } // 原來的組件 import uniqueID from './helper'; export default { methods: { getID(increase = true) { let id = uniqueID(increase); return `my-component-${this.selfIndex}-${id}`; } } }
順便作個廣告,個人新講堂已經上線,將於下週二直播。測試
此次我決定把本身積累的面試題詳細地介紹給全部來聽課的同窗。從設置這道題的目的,考察的方向,但願聽到的答案,答出多少大約是什麼評價等等都來個完全的公開。相信你們聽後,能夠更加明確平常學習的方向。this
目前還在75折銷售中,歡迎你們,連接在此。
這兩天聽評書《亂世梟雄》,學到一句話「拉屎臉朝外」,形容講義氣,不知道咋聯繫的……
同步於 個人博客。