Попередження консолі: списки компонентів, які відображаються за допомогою v-for, повинні мати явні ключі


76

У мене тут проблема, я не знаю, що не так у моєму коді, але я отримав попередження на консолі, як я можу видалити це попередження?

[Підказка 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 . Я думаю, у мене немає помилок, я хочу вирішити це попередження, але я не можу знайти, де причина, до речі, я новачок тут, до Vue.

Відповіді:


108

Відповідь прямо вказана в документації, яку ви зв’язали ...

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

Щоб підсумувати деяку інформацію з коментарів нижче ... ви використовуєте, :keyщоб дати компоненту знати, як ідентифікувати окремі елементи. Це дозволяє йому відстежувати зміни щодо реакційної здатності Vue .

Найкраще спробувати прив’язати :keyдо якоїсь унікальної властивості кожного предмета. Наприклад, id.


1
У моєму випадку я хочу, щоб весь об'єкт todo передавався <todo-item>, я не хочу передавати лише .text. Чи можливо це?
Кокодоко

@kokodoko весь пункт буде прийнятий через dataвласність. Ви використовуєте, keyщоб дати компоненту знати, як ідентифікувати окремі елементи
Філ,

1
добре, спасибі, тому ключ - це лише спосіб для vue відстежувати речі, тому вам потрібно мати якесь значення, яке використовуватиметься як ключ.
Кокодоко,

1
@Kokodoko так, це саме те
Філ

7

Моє рішення подібної проблеми виглядало так:

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

Або використання v-bindсинтаксису для index:

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

Це чудове рішення. Мої елементи насправді не унікальні. Отже, це вирішує.
хан

1

Ви можете використовувати будь-яке поле ваших даних як ключ. Крім того, ви можете використовувати ідентифікатор за замовчуванням. Крім того, ви можете визначити "ключ" у своїх даних, як у коді нижче:

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 можна поставити одне з імен полів, включаючи прихований ідентифікатор.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.