首先明确,我遇到这个问题时是v-for嵌套的情况。Vscode使用了Vetur插件。如果你遇到的相同的报错但是与我的原因不同,可以在评论区中留言,我看到后也会尽可能帮助你解决问题。
我将出现问题的代码抽象成如下结构
<template v-for="(item1, index1) in ['str1','str2','str3']">
<div :key="index1">div>
<template v-for="(item2, index2) in [0,1,2,3,4]">
<div :key="index2" v-if="item===4">div>
template>
template>
报错的是第二个template标签下绑定的key
这问题我在思否上提过:Vue2.0中嵌套v-for结构的第二个key为什么总是报错?
最后是我自己找到的解决办法。
乍一看,好像是eslint配置的问题,不过我想声明,埋怨并修改eslint配置问题不是我所期望的解决办法,既然eslint报错了,那么就意味着代码的写法或者风格不符合规范,而我所探寻的就是怎么写才是符合规范的。
如果你只想关闭烦人的错误提示,很简单。在VsCode设置中搜索eslint,找到下面这个设置
关闭即可关掉错误提示。
但正如我所说,关掉它不是我所期待的解决方法。
那么来看正确的解决办法吧。
它是我准备在Stack Overflow上提问题时发现的已存在问题Expected v-bind directive on complex / v-for
可以看到该问题中,提问者的代码结构与我完全一致
<template v-for="(scorecard, scorecardIndex) in scorecards">
<template v-for="(property, propertyIndex) in properties">
<tr v-if="scorecardIndex === 0"
v-bind:key="propertyIndex">
tr>
template>
<tr v-if="scorecardIndex > 0"
v-bind:key="scorecardIndex">
tr>
template>
我删掉了一些不相干的内容,留下的核心的结构。我们都是两层v-for,并且两层v-for都在template标签上。
首先key是不能在template标签上绑定的,因为它不是实际被渲染到dom上的内容,只接受控制属性。所以key的绑定规范是绑定到template标签下一级的dom结构上,如果template标签下有多个同级结点,那么每一个同级结点都要绑定该template标签v-for中定义的变量的key。
key的绑定规范如上所述,所以第二个template标签下的内容绑定key也需如此。以我的代码为例,注意看注释
<template v-for="(item1, index1) in ['str1','str2','str3']">
<div :key="index1">div>
<template v-for="(item2, index2) in [0,1,2,3,4]">
<div :key="index2" v-if="item===4">div>
template>
template>
按照回答者的原话
You need to make sure that the key of the first < tr > uses variables defined by both v-fors.
这个tr是Stack Overflow上提问者的第二个template标签下的内容,也是我上述代码中注释下的那个div标签
所以这个问题正确解决办法是,同时绑定两个v-for中定义的变量,如下所示(以我的代码为例)
<div :key="index1+index2">div>
其实怎样绑定也行,只要这个key值,与两个v-for中的变量有关即可。
回顾这个问题,其实它并不只发生在两个v-for在两个template标签上。
如下代码
<template v-for="item1 in ['str1','str2','str3']">
<div :key="item1">div>
<div v-for="item2 in [1,2,3]" :key="item2">div>
template>
上图为原uni-app代码,view标签等价于div标签
可以看到它仍然报了这个问题的错误,正确应该是
<template v-for="item1 in ['str1','str2','str3']">
<div :key="item1">div>
<div v-for="item2 in [1,2,3]" :key="item1+item2">div>
template>
至此,问题解决完毕