Console warning: component lists rendered with v-for should have explicit keys

Javascriptvue.jsVuejs2

Javascript Problem Overview


I got a problem here, I don't know what is wrong in my code, but I got a warning in my console, how can I remove this warning?

> [Vue tip]: <todo-item v-for="todoItem in todos">: component lists rendered with v-for should have explicit keys. See https://vuejs.org/v2/guide/list.html#key for more info.
(found in <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

enter image description here

Here is the link that Vue suggested here. I think i don't have any error, I want to solve that warning but I cannot find where's the cause, btw I'm newbie here to Vue.

Javascript Solutions


Solution 1 - Javascript

The answer is listed explicitly in the documentation you linked...

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

To summarise some information from the comments below... you use :key to let the component know how to identify individual elements. This allows it to keep track of changes for Vue's reactivity.

It's best to try and bind the :key to some uniquely identifying property of each item. For example, an id.

Solution 2 - Javascript

My solution to a similar problem looked like this:

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

Or using v-bind syntax for index:

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

Solution 3 - Javascript

You can use any field of your data as a key. In addition you can use the default id. Furthermore you can define a "key" in your data as in the code below:

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>`
});

In the place of the key in the task.key you can put one of the field names including the hidden id.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn Rey M. BaylenView Question on Stackoverflow
Solution 1 - JavascriptPhilView Answer on Stackoverflow
Solution 2 - JavascriptHenryView Answer on Stackoverflow
Solution 3 - JavascriptIoannis ChrysochosView Answer on Stackoverflow