91

Vue.js 2.5 / Visual Studio Code editor

I am getting this es-lint warning, how can I get rid of it ?

<template :slot="slotName" slot-scope="props" v-for="slotName in  $scopedSlots?Object.keys($scopedSlots):null">
    <slot :name="slotName" :row-data="props.rowData" :row-index="props.rowIndex" :row-field="props.rowField"></slot>
</template>

I tried to add an index, but it does not solve this issue

<template :slot="slotName" slot-scope="props" v-for="(slotName, index) in  $scopedSlots?Object.keys($scopedSlots):null" :key="index">
    <slot :name="slotName" :row-data="props.rowData" :row-index="props.rowIndex" :row-field="props.rowField"></slot>
</template>
Amir Jani
  • 380
  • 6
  • 16
  • 2
    Possibly put the `key` on the `slot` element rather than the `template` element? – Roy J Dec 02 '17 at 14:00
  • @Roy , thanks for your feedback... I tried it, es-lint warning disappear , but git a compilation error : - `key` does not work on because slots are abstract outlets and can possibly expand into multiple elements. Use the key on a wrapping element instead. –  Dec 02 '17 at 15:59
  • can you reply as an answer ... I'll vote for it... I can add the :key bonding on a
    wrapper !
    –  Dec 02 '17 at 16:02

8 Answers8

157

This structure causes the said error:

<div v-for="(item, index) in items">
    {{index}}. {{item.name}}
</div>

You can fix it by changing the syntax like this:

<div v-for="(item, index) in items" :key="item.id">
    {{index}}. {{item.name}}
</div>

If your items do not have any unique id field you can just write :key="item". However, for performance reasons your data should have an id field.

https://v2.vuejs.org/v2/guide/list.html#key

tony19
  • 125,647
  • 18
  • 229
  • 307
ESP32
  • 8,089
  • 2
  • 40
  • 61
22

You can safely ignore that warning. It comes from the eslint plugin for vue and it was a bug, got fixed a month ago but maybe vetur is still using the old version of the plugin.

The key attribute has to be added to the content you pass to your component

Posva
  • 1,104
  • 9
  • 15
  • 1
    thanks for feedback... I can ignore it, but I also can add the :key binding inside a wrapping element in the slot –  Dec 03 '17 at 08:05
  • 1
    Yes, you can :), it's easier if you know how to extract a `key` from the data. But if your component is rendering arbitrary data, you have no choice but to leave the user of your component provide that information (eg: a virtual scroller) – Posva Dec 04 '17 at 08:41
  • thanks .. if no key in the data, I can add index and use it... it's running fine too –  Dec 04 '17 at 11:31
  • 2
    It's not a good idea to use the index as the key, that's the default behaviour when no `key` is provided – Posva Dec 05 '17 at 10:12
  • 1
    Funny, I upgraded my eslint-plugin-vue to 5.0.0-beta.1 (the fix version) and it reports it as an error instead of just a warning. – Patrick Aug 04 '18 at 03:37
  • Yep, I had to straight up add the `:key` directive. It may be due to me running node v10 though. – Patrick Aug 04 '18 at 03:45
  • The warning still there in 2021. I used the id as key. Another option is to disable eslint for that specific line: https://stackoverflow.com/questions/27732209/turning-off-eslint-rule-for-a-specific-line (Remember to yarn serve to see the changes if you are using hot reload) – Arjuna Deva Mar 16 '21 at 14:18
14

Let's look at a simple example here!

I'm building a To do List App. So I build a component called Todo and inside my TodoList component I will call Todo component like this

    <todo v-for="todo in todos" v-bind:key="todo" v-bind:todo="todo"></todo>

Hope it helps!

Travis Le
  • 432
  • 1
  • 5
  • 7
10

Hope this works.

Parent Component

<template>
  <ul>
    <VideoListItem v-for="video in videos" v-bind:key="video.title" v-bind:video="video"></VideoListItem>
  </ul>
</template>

<script>
import VideoListItem from "./VideoListItem";

export default {
  name: "VideoList",
  components: { VideoListItem },
  props: ["videos"]
};
</script>

Child Component

<template>
  <li>{{ video.snippet.title}}</li>
</template>

<script>
export default {
  name: "VideoListItem",
  props: ["video"]
};
</script>

<style scoped>
</style>

======================================================

Listen => when ever you provide v-for property we need to provide v-key property. IT ENHANCES THE PERFOMANCE OF RERENDER OUR LIST OF ITEM.

Khalifa Vhy
  • 101
  • 1
  • 4
8
<li class="list-group-item" v-for="server in Servers" v-bind:key="server">    

Specify the unique key in the tag like this.

chetan pai
  • 81
  • 1
  • 2
  • In my opinion this is the correct answer. OP needs to define the v-bind parameter in order to be recognized (if you have an array of objects) – Lepy Feb 25 '22 at 11:25
7

Suppose you are iterating over an array named users, then you can do something like this:

<div v-for="(user,id) in users" :key="id" >
      <div class="card" >
       ...........................
      </div>
</div>
hardik chugh
  • 1,082
  • 15
  • 12
3

this work for me

<div :class="sliderClass()" v-for="(slide,index) in slides" :key="index">
<div :class="sliderClass()" v-for="slide in slides" :key="slide.SliderID">
Omid Matouri
  • 157
  • 5
1

Here is the discussion in eslint-plugin-vue, which has the following workaround suggested:

"vetur.validation.template": false,

Which corresponds to this UI option:

enter image description here

Guess no eslint validation in html is better than incorrect validation.

Klesun
  • 12,280
  • 5
  • 59
  • 52