今天写着写着,忽然发现控制台里有错误: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折销售中,欢迎你们,连接在此。
这两天听评书《乱世枭雄》,学到一句话“拉屎脸朝外”,形容讲义气,不知道咋联系的……
同步于 个人博客。