Subscribe on changes!

Warnings/Types for the key attribute

avatar
Nov 18th 2020

Version

3.0.2

Reproduction link

https://jsfiddle.net/skirtle/2czyf41n/

Steps to reproduce

The example illustrates a couple of things:

  1. Using objects for the key attribute works (this is good but undocumented).
  2. No warning is shown when using the same key (value 1) for multiple adjacent siblings.

What is expected?

A quick recap of Vue 2:

  1. Keys had to be primitives: string, number, boolean or symbol. Anything else triggered an immediate warning during rendering.
  2. Using the same key on siblings triggered a warning about duplicate keys.

Observations about Vue 3:

  1. From looking through the code it seems that keys are compared using ===. In some edge cases they are compared using a Map. Either way, objects can now be used as keys. I think this is great.
  2. From a TS perspective, keys are only permitted to be a string or number.
  3. There is a warning about duplicate keys but it is only hit during updates and only in very specific circumstances.

Based on my best guess about what the expected behaviour is I suggest the following changes:

  1. There should be a warning during rendering for duplicate keys. Duplicates indicate a developer error, even if they cause no real harm.
  2. The TS definitions should be updated to allow anything to be used as a key.
  3. The docs should be updated. Being able to use an object as a key is a great new feature and, if it's intentional, it's something worth shouting about. I'm happy to make the docs changes myself once I have confirmation of the officially supported behaviour.
avatar
Nov 19th 2020

https://github.com/vuejs/docs-next/issues/698

And,

  1. how should NaN -0 be treated?
  2. I saw v-if/v-else is auto compiled to key:0 key:1 in the source. won't that cause error when the sibling is key=0 key=1 or other v-if/v-else also compiled to key:0 key:1?
avatar
Mar 12th 2021

I saw v-if/v-else is auto compiled to key:0 key:1 in the source. won't that cause error when the sibling is key=0 key=1 or other v-if/v-else also compiled to key:0 key:1?

The compiled render function will enter the optimization mode when patching, it respects the so-called block-tree algorithm, which has nothing to do with the key.

avatar
Mar 12th 2021

This PR provides the checking for duplicate keys

avatar
Mar 30th 2021

Just to clarify, adding the duplicate keys warning was just one, small part of this.

Primarily I was trying to get the types updated with a view to updating the docs.

avatar
Nov 28th 2023

Hey guys, just want to add another reason why I believe there should be a warning for siblings with the same key: Previously there was an issue when siblings were not updated when using v-if, so this got fixed for vue templates in the compiler by automatically adding keys: https://github.com/vuejs/core/issues/1587 However, we ran into the same issue when using JSX: https://github.com/vitejs/vite-plugin-vue/issues/304 I believe that by having proper checks in place for keys this issue could be avoided.