Warnings/Types for the key attribute
Version
3.0.2
Reproduction link
https://jsfiddle.net/skirtle/2czyf41n/
Steps to reproduce
The example illustrates a couple of things:
- Using objects for the
key
attribute works (this is good but undocumented). - No warning is shown when using the same
key
(value1
) for multiple adjacent siblings.
What is expected?
A quick recap of Vue 2:
- Keys had to be primitives: string, number, boolean or symbol. Anything else triggered an immediate warning during rendering.
- Using the same
key
on siblings triggered a warning about duplicate keys.
Observations about Vue 3:
- From looking through the code it seems that keys are compared using
===
. In some edge cases they are compared using aMap
. Either way, objects can now be used as keys. I think this is great. - From a TS perspective, keys are only permitted to be a string or number.
- 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:
- There should be a warning during rendering for duplicate keys. Duplicates indicate a developer error, even if they cause no real harm.
- The TS definitions should be updated to allow anything to be used as a key.
- 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.
https://github.com/vuejs/docs-next/issues/698
And,
- how should
NaN
-0
be treated? - I saw
v-if/v-else
is auto compiled tokey:0
key:1
in the source. won't that cause error when the sibling iskey=0
key=1
or otherv-if/v-else
also compiled tokey:0
key:1
?
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
.
This PR provides the checking for duplicate keys
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.
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.