控制台警告:用 v-for 渲染的组件列表应该有明确的键

Posted

技术标签:

【中文标题】控制台警告:用 v-for 渲染的组件列表应该有明确的键【英文标题】:Console warning: component lists rendered with v-for should have explicit keys 【发布时间】:2017-07-17 13:06:52 【问题描述】:

我在这里遇到了问题,我不知道我的代码有什么问题,但是我在控制台中收到了警告,我该如何删除这个警告?

[Vue 提示]:<todo-item v-for="todoItem in todos">:使用 v-for 渲染的组件列表应该有明确的键。请参阅https://vuejs.org/v2/guide/list.html#key 了解更多信息。 (发现于<Root>

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue Tutorial</title>
        <link rel="shortcut icon" href="https://vuejs.org/images/logo.png">
        <script src="scripts/vue.js"></script>
    </head>
    <body>
        <section id="app">
            <p> msg </p>
            <p v-bind:title="message">
                Hover your mouse over me for a few seconds to see my dynamically bound title!
            </p>
            <div>
                <p v-if="seen">This text will show or hide if the button was clicked.</p>
                <button type="button" v-on:click="isSeen"> isSeenText </button>
            </div>
            <ol>
                <li v-for="todo in todos">
                     todo.text 
                </li>
            </ol>
            <p>Total count:  todos.length </p>
            <div v-bind:title="reverseMessageText">
                <p> reverseMessageText </p>
                <button v-on:click="reverseMessage">Reverse Message</button>
            </div>
            <div>
                <p>Data binding: <strong> nameOfUser </strong></p>
                <input type="text" v-model="nameOfUser">
            </div>
            <div>
                <ol>
                    <todo-item v-for="todoItem in todos" v-bind:data="todoItem"></todo-item>
                </ol>
            </div>
        </section>
        <script src="scripts/app.js"></script>
    </body>
</html>

app.js

var appComponent = Vue.component('todo-item', 
    template: '<li>id:  data.id <br>text:  data.text </li>',
    props: [
        'data'
    ]
);

new Vue(
    el: '#app',
    data: 
        msg: 'Hello World!',
        message: 'You loaded this page on ' + new Date(),
        seen: true,
        isSeenText: 'Now you don\'t',
        todos: [
            
                text: 'Learn javascript'
            ,
            
                text: 'Learn Vue'
            ,
            
                text: 'Build something awesome'
            
        ],
        reverseMessageText: 'Hello World from Vue.js!',
        nameOfUser: 'John Rey'
    ,
    methods: 
        reverseMessage: function() 
            this.reverseMessageText = this.reverseMessageText.split('').reverse().join('');
        ,
        isSeen: function() 
            this.seen = !this.seen;
            this.isSeenText = this.seen ? 'Now you don\'t' : 'Now you see me';
        
    
);


console.log

这是 Vue 建议的链接 here。我想我没有任何错误,我想解决那个警告,但我找不到原因,顺便说一句,我是 Vue 的新手。

【问题讨论】:

【参考方案1】:

答案明确列在documentation you linked...

<todo-item v-for="todoItem in todos"
           v-bind:data="todoItem"
           v-bind:key="todoItem.text"></todo-item>

总结以下 cmets 的一些信息...您使用:key 让组件知道如何识别单个元素。这允许它跟踪 Vue 的 reactivity 的变化。

最好尝试将:key 绑定到每个项目的某些唯一标识属性。例如,id

【讨论】:

在我的情况下,我希望将整个 todo 对象传递给 ,我不想只传递 .text。这可能吗? @kokodoko 整个项目通过data 属性传递的。您使用key 让组件知道如何识别单个元素 好的,谢谢,所以key只是vue跟踪事物的一种方式,所以你需要有一些价值来用作key。 @Kokodoko 是的,就是这样【参考方案2】:

我对类似问题的解决方案如下所示:

- <el-radio v-for="option in field.options"> ...
+ <el-radio v-for="(option, index) in field.options" :key="index"> ...

或者对index使用v-bind语法:

+ <el-radio v-for="(option, index) in field.options" v-bind:key="index"> ...

【讨论】:

这是一个很好的解决方案。我的元素并不是真正独特的。这样就解决了。 @khan 除非您的“选项”列表是静态的,否则这对于 OP 的问题来说是一个非常糟糕的解决方案。由于渲染的项目将通过它们在列表中的位置来识别,因此任何重新排序列表的风险都很难找到错误。【参考方案3】:

您可以将数据的任何字段用作键。此外,您可以使用默认 ID。此外,您可以在数据中定义一个“键”,如下面的代码所示:

Vue.component('task-list', 
template:  `
<div><slot>
    <task v-for="task in tasks" :key="task.key">  task.description</task>
</slot></div>
`,
data () 
    return 
        tasks: [
                description:"Go to market", completed:false, key:"asd",
                description:"Wake up ", completed:true, key:"rty",
                description:"Sleep", completed:false, key:"terw",
                description:"Have breakfast", completed:true, key:"jdr",
        ]
    ;
,
);
Vue.component('task', 
   template: `<li><slot></slot></li>`
);

在 task.key 中的键的位置,您可以放置​​一个字段名称,包括隐藏的 id。

【讨论】:

以上是关于控制台警告:用 v-for 渲染的组件列表应该有明确的键的主要内容,如果未能解决你的问题,请参考以下文章

Vue列表渲染

Vue2子组件对象v-for列表渲染的奇怪问题

vue组件5 组件和v-for指令

Vue.js - 组件模板不使用 v-for 渲染

v-for

如何避免重新渲染由 v-for 指令创建的所有子组件