Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'v-for' directives require 'v-bind:key' directives. #261

Closed
ideal123 opened this issue Jun 23, 2017 · 92 comments
Closed

'v-for' directives require 'v-bind:key' directives. #261

ideal123 opened this issue Jun 23, 2017 · 92 comments
Labels

Comments

@ideal123
Copy link

  • Platform: win10
  • Vetur version: 0.8.3
  • VSCode version: 1.13.1

'v-for' directives require 'v-bind:key' directives when I use <li class="item-right" v-for="n in 19">{{ n }}</li>.

@ideal123
Copy link
Author

_20170623122147

@emrekaranfil
Copy link

I have with this problem. I did not understand why.

capture1
2017-06-23 07_42_32-posted vue - havacidan-com-development-95cc0e97636358ee5c366238802bd899bec30e9d
2017-06-23 07_44_40- mainfeed vue - havacidan-com-development-95cc0e97636358ee5c366238802bd899bec30
2017-06-23 07_46_25-authentication vue - havacidan-com-development-95cc0e97636358ee5c366238802bd899b

@topul
Copy link

topul commented Jun 23, 2017

In 2.2.0+, when using v-for with a component, a key is now required.

@topul
Copy link

topul commented Jun 23, 2017

but, this is still a bug

_20170623134735
_20170623134758

@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Jun 23, 2017

@ideal123 This is intended ESLint feature. You can turn off eslint check in future release. See #235 (comment)

@emrekaranfil Would you mind provide an example repo for this problem? It seems eslint is reporting at wrong location.

@topul This is a valid bug! Ping @mysticatea, any idea? An upstream pull request is already here. vuejs/eslint-plugin-vue#45

@ideal123
Copy link
Author

@topul I use v-for with a html element, and a key is unnecessary

@HerringtonDarkholme I disabled ESlint Plugin, but there is the same error.

@HerringtonDarkholme
Copy link
Member

@ideal123 ESLint support is builtin with vetur. Please peruse #235. Closing vetur's builtin eslint has already been scheduled.

For the bug in this issue, it has been extracted in #263 and fixed in #264.

So close this issue now.

@Villae
Copy link

Villae commented Jul 7, 2017

I think that this is still issue with vetur version 0.8.6.
"In 2.2.0+, when using v-for with a component, a key is now required."

-> key is required with a component, but it should not be required with a html element like <li> (in ideal123's case) or <option> (in my case), etc.

@octref
Copy link
Member

octref commented Jul 7, 2017

I'll publish a new version soon!

@SmileyChris
Copy link

SmileyChris commented Jul 24, 2017

I see v0.0.10 was released 12 days ago, but I'm not sure it contained a fix for this. If it did not, perhaps this issue should be reopened since it seems it is still a problem currently.

@octref
Copy link
Member

octref commented Jul 24, 2017

Forgot to update dependency for eslint...
Try 0.9.3 or upgrade local eslint-plugin-vue@beta.

@grugknuckle
Copy link

I am still getting a form of this error. I have Vetur 0.9.3 installed as plug-in to VS Code. I have globally installed eslint-plugin-vue@beta and eslint4.3.0. But in my .vue file I have

vetur_err

[vue-language-server] Elements in iteration expect to have 'v-bind:key' directives.

I should point out that VS Code gives me complaint when I copy&paste the basic usage code directly frrom the Vue.js documentation..

@octref
Copy link
Member

octref commented Aug 2, 2017

The behavior only depends on eslint-plugin-vue@beta installed locally.

@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Aug 2, 2017

@grugknuckle This is intended feature from eslint-vue.

https://github.com/vuejs/eslint-plugin-vue/pull/45/files#diff-b013f11a89eed99206147599342d1bbdR51

You can turn off vetur's lint and use vscode-eslint to customize your rules. Also, raising a proposal for eslint-plugin-vue is a good choice.

@grugknuckle
Copy link

Ok. Thank you. I can see that this is working as intended in the sense that there is a unit test for it.

Can anyone explain why this test is here? What is the purpose of throwing an invalid warning on code which is identical to what it suggested in the vue.js documentation for the v-for directive? See for example, the basic usage code here

https://vuejs.org/v2/guide/list.html#Basic-Usage

I'm just curious as to what code pattern this is supposed to prevent. So that I can do it right.

@mysticatea
Copy link
Member

There are 2 rules about v-for and v-bind:key. One is vue/no-invalid-v-for in "Possible errors" category. This reports custom components which don't have v-bind:key. One is vue/require-v-for-keys in "Best practice" category. This reports normal elements which don't have v-bind:key.

Vue core team has recommended to use v-bind:key at all, but it's not errors on non custom components which don't have v-bind:key, so you can disable vue/require-v-for-keys.

@grugknuckle
Copy link

Perfect! Thank you.

@think2cat
Copy link

maybe vscode only, webstorm have not report this error

@hryamzik
Copy link

The behavior only depends on eslint-plugin-vue@beta installed locally.

@octref so does it come as a dependency? Does it have to be updated in some specific way?

@RobinHerbots
Copy link

@grugknuckle ,

add v-bind:key="the key property" on your li item

@aprilandjan
Copy link

Suuuper annoying! Everytime I opened the vue files developed by other colleagues, the red lines
blinded my eyes!

@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Sep 8, 2017

I don't want to be rude. But I hope someone can read the doc before complaining about their visual handicap.

https://github.com/vuejs/vetur/blob/master/docs/linting-error.md#linting

Again, VueJS recommend to add key to every element and component. Adding an eslint step to your project and teaching your teammate is a good choice.

It is recommended to provide a key with v-for whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.

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

@SaphiLC
Copy link

SaphiLC commented Sep 7, 2018

i dont understand why this is REQUIRED when the docs say its recommended, even more

<div :id="'tag-' + index" v-for="tag in tags" :key="index">

results in an id of "tag-undefined" while

<div :id="'tag-' + index" v-for="(tag, index) in tags">

results in "tag-0" etc but with error in the IDE, and adding both

<div :id="'tag-' + index" v-for="(tag, index) in tags" :key="index">

feels stupid and not necesary since its defining the key twice (?)

(and no, you cant add :key to a template tag, so thats not a solution)

@nickforddev
Copy link

@SaphiLC You're not defining the key twice, you're choosing to use it twice. Why not skip the ID altogether? 99% of the time, unless you are dealing with <label> for inputs, there is a better solution than using ids.

@tvviem
Copy link

tvviem commented Sep 8, 2018

@DamengRandom
Copy link

please check official doc (v-for) part, solution was add :key="item.id".

@Anzimanpkp
Copy link

Anzimanpkp commented Oct 12, 2018

The error:: [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives
This error appears when the editor wants you to provide the 'v-bind:key'.
As, this error doesnot effect the execution of the code, you can easily run the code.But if you want to resolve this error, then use the 'key' for v-for.
Example::::

<li v-for="details in retrieve_Allusers" :key="details"></li>
The above code contains a key for 'v-for' directive. If you want to resolve the error, providing the key in v-for will be the best solution.

@lytecode
Copy link

@Anzimanpkp's solution worked like a magic for me.
Just add :key="somekey" to you code.

<li v-for='hero in heros' v-on:click='hero.show = !hero.show' :key="hero">

Thanks @Anzimanpkp

@tvquangdn
Copy link

Code like this: <div v-for="x in list" :key="x.id"></div>
https://github.com/mysticatea/eslint-plugin-vue-trial/blob/master/docs/rules/require-v-for-key.md

@bincute
Copy link

bincute commented Jan 17, 2019

You should add :key="x.id" or :key="other". "It is recommended to provide a key with v-for whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains." form Vue documents.

@omid265
Copy link

omid265 commented Mar 5, 2019

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">

@malcoded
Copy link

malcoded commented Apr 7, 2019

<li v-for="categoria in arrayCategoria" :key="categoria.id">

@tvkit
Copy link

tvkit commented Apr 11, 2019

Just add the :key ...

If that wasn't obvious...

The following is not an uncommon usage of v-for. How would the vue/require-v-for-key check be satisfied?

<table>
  <template v-for="row in rows">
    <tr><td>{{row.text}}</td></tr>
  </template>
</table>

@grugknuckle
Copy link

The following is not an uncommon usage of v-for. How would the vue/require-v-for-key check be satisfied?

@tvkit It's an easy modification of your code. Assuming that rows is an array, you can add this.

<table>
  <template v-for="(row, index) in rows" :key="index">
    <tr><td>{{row.text}}</td></tr>
  </template>
</table>

See my comment above about why this is really a problem with the vue.js documentation and NOT a problem with the vetur implementation of this rule.

@incompletude
Copy link

I'm getting the error message when I don't need a key.

      <ul class="dropdown">
        <template v-for="(item, index) in items">
          <li v-bind:key="item.value">
            <a href>{{ item.text }}</a>
          </li>
          <template v-if="items[index + 1]">
            <li class="divider" v-if="item.group !== items[index + 1].group">a</li><!-- error -->
          </template>
        </template>
      </ul>

@paulcdejean
Copy link

paulcdejean commented May 15, 2019

@grugknuckle your code gives the error - <template> cannot be keyed. Place the key on real elements instead.

@Timmmm
Copy link

Timmmm commented Dec 20, 2019

I think this lint should be disabled. It clearly doesn't work properly.

  • :key is NOT required in general. It is only required if your elements have state, so that Vue can keep track of them. If they are stateless (e.g. a simple <li>, <a> or <p>) then it is NOT required.
  • You can work around it by using the index as a key: v-for="(el, idx) in items" :key="idx". This is equivalent to not including a key at all and shouldn't be necessary.

This lint can be disabled until it can reliably detect that the elements contain state.

@sam-spain
Copy link

I found this rule to not be helpful with the project I am working in and have disabled it. I am using VS Code and set up the ESLint extension. https://eslint.org/docs/user-guide/getting-started

In settings.json I disabled vetur's validation for templates with "vetur.validation.template": false"

And then in my rules for es lint (.eslintrc.js for me) I set "vue/require-v-for-key": "off"

I think this is less disruptive than changing each v-for when we are only iterating through data that will be static for the purpose of displaying. I haven't managed to get it to work with ignoring line below or entire file as they would be more preferable for some.

@jdspugh
Copy link

jdspugh commented Jan 24, 2020

Keys are used as hashes to optimise DOM rendering. If incorrectly used they will slow performance and use more memory over automatically generated keys. People who don't understand what makes a good key will be generating poorer performance UIs than auto generated keys. That's why keys should be optional. Apart from the fact it's very annoying getting these errors and existing code shows errors.

@Timmmm
Copy link

Timmmm commented Jan 30, 2020

I've also tried adding this to my .eslintrc.js file's rules section, but it seems to be ignored by Vetur:

"vue/require-v-for-key": "off",

Timmmm added a commit to Timmmm/eslint-plugin-vue that referenced this issue Jan 30, 2020
This lint is too restrictive, and isn't able to detect the cases when it is wrong.

See vuejs/vetur#261
@begueradj
Copy link

As mentioned previously, we need to bind the key prop to a value. For example:

<div v-for="(item, index) in items">
  <!-- do stuff -->
 </div>

But is there a way to disable this rule ? There are multiple situations where it should be put off, for example when we work with slots.

@Silly-V
Copy link

Silly-V commented Mar 3, 2020

Is there some other extension which doesn't make these squiggly lines?

AHA! I figured out my personal issue - I never used parentheses ever! Now that I put parentheses in, the squiggly lines go away!

Thank you dear Vetur developers for your hard work. If someone else is frustrated with this, I will tell them my solution!

@bmaca
Copy link

bmaca commented Apr 5, 2020

Just adding my simple solution down to this just in case runs into it later on.
To the initial question <li class="item-right" v-for="n in 19">{{ n }}</li>

After Vue 2.2 this does not work in the latest Vue and throws an error. It needs have a v-bind:key directive

The fix is as simple as adding a key like this: <li class="item-right" v-for="n in 19" :key="n">{{ n }}</li>

@poonamrani
Copy link

You should be using older version of VueJS but in latest versions key binding is mandatory to improve the performance of rendering the v-for elements. So please update your VueJS and check this.

To add v-bind:key you have to do something like this.

  • Hope this answers your question.

  • @exse2
    Copy link

    exse2 commented Jul 13, 2020

    in latest versions key binding is mandatory

    No. See https://vuejs.org/v2/api/#v-for

    @calumk
    Copy link

    calumk commented Jan 26, 2021

    +1 - Key does not seem to be mandatory, so why is an error forced here?

    @yoyo930021
    Copy link
    Member

    yoyo930021 commented Jan 26, 2021

    Reason: #261 (comment)

    If you don't need this rule, you can disable vetur.validation.template: false and use ESLint for validate template.

    I will lock this issue.
    Please open a new issue when you have problem.

    @vuejs vuejs locked as resolved and limited conversation to collaborators Jan 26, 2021
    Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
    Labels
    Projects
    None yet
    Development

    No branches or pull requests