一个vue for绑定key引发的错误及解决过程
一次项目中,需要用v-for渲染problem子组件。原本的代码是这样的:
<problem v-for="(prob,ind) in probs" :key="ind"></problem>
这里用数组下标作为key绑定。
父组件中有一个从probs数组中删除一项的方法,原本期望通过这个方法能删除页面上的子组件。
然而,实际使用时,若删除probs的第k项,网页上并不会将第k个problem组件删除,而是最后一个。
经过研究,发现是key的问题。原本绑定的ind是数组的下标,但删除probs数组的一项后,后续的下标又会更新,所以不能正确删除期望的组件。
摘录vue官方对此问题的解释:
vue官方的解决方法是,给数组的每一项都加上一个真正独一无二的id属性。
照此方法,我想在组件的mounted钩子中给probs数组的每项添加id属性。
以下是最初的写法,在组件的data中加入一个uniqueCounter属性:
this.probs.forEach((prob)=>{prob.id=this.uniqueCounter++});
我觉得可以再封装。如果有多个数组需要像这样分配id,你一定不想写:
this.probs.forEach((prob)=>{prob.id=this.uniqueCounter++}); this.quests.forEach((quest)=>{quest.id=this.uniqueCounter++}); ......
我认为比较好的方法是写一个闭包计数器。在data中定义这个计数器:
uniqueId:(function () { let id=0; return function () {return id++;}; })(),
使用计数器:
this.probs.forEach((prob)=>{prob.id=this.uniqueId()}); this.quests.forEach((quest)=>{quest.id=this.uniqueId()}); ......
这样终于解决了问题。