sometimes template can not apply key by v-for
Link to minimal reproduction
Steps to reproduce
None.
What is expected?
Works.
What is actually happening?
It report error.
System Info
System:
OS: macOS 12.3.1
CPU: (10) arm64 Apple M1 Max
Memory: 2.97 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.15.0 - /opt/homebrew/opt/node@16/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.5.5 - /opt/homebrew/opt/node@16/bin/npm
Browsers:
Chrome: 101.0.4951.64
Firefox: 100.0.1
Safari: 15.4
Any additional comments?
Moving the :key
binding from <template>
to <slot>
resolves the issue:
<van-loading>
<template v-for="(_, slot) of $slots" v-slot:[slot]="scope">
👇
<slot :name="slot" v-bind="scope" :key="slot" />
</template>
</van-loading>
Moving the
:key
binding from<template>
to<slot>
resolves the issue:<van-loading> <template v-for="(_, slot) of $slots" v-slot:[slot]="scope"> 👇 <slot :name="slot" v-bind="scope" :key="slot" /> </template> </van-loading>
Thanks for your quick reply.
Please look at componentB
in the copied link, is this another problem?
Your usage in that blitz doesn't make sense to me. To forward the default slot, just use <slot/>
:
<template>
<van-loading v-bind="$attrs">
<slot />
</van-loading>
</template>
Thanks for your help, adding the key
to the slot
solved my problem, there's only one lint error left that confuses me. https://github.com/vuejs/eslint-plugin-vue/issues/1900 I disabled the rule to make it works.
Not sure about the key
issue. I'm wondering if <template>
's key
is supposed to be automatically applied to <slot>
children. Nothing in the docs suggests the key
should be manually/explicitly moved to the children, so it might be a Vue bug after all (not a linter bug). 🤔
Not sure about the
key
issue. I'm wondering if<template>
'skey
is supposed to be automatically applied to<slot>
children. Nothing in the docs suggests thekey
should be manually/explicitly moved to the children, so it might be a Vue bug after all (not a linter bug). 🤔
So do you think this needs to be fixed in vue
? Alternatively, others who got this error should also take the solution you gave me as the final solution?
So do you think this needs to be fixed in
vue
?
Yes, I think so. But the template in the original repro is invalid IMO (see comment). I recommend creating a new issue with valid markup that generates the error.
Alternatively, others who got this error should also take the solution you gave me as the final solution?
Assuming the key
issue is indeed a Vue bug, adding the key
binding to the <slot>
(and disabling the linter warning for those lines only) is a reasonable workaround for the time being.
Yes, I think so. But the template in the original repro is invalid IMO (see comment). I recommend creating a new issue with valid markup that generates the error.
I've updated it https://stackblitz.com/edit/vue3-forwarding-slots-qmswhv?file=src%2FApp.vue,src%2Fcomponents%2FComponentA.vue
any update on this ?
I have this code part of a Vue 3 migration :
<template>
<v-card
rounded="0"
:loading="loading"
>
<v-card-title>
Exécutions
</v-card-title>
<v-list class="py-0">
<template v-if="runs">
<template v-for="run in runs.results">
<v-divider :key="run._id + '-divider'" />
<run-list-item
:key="run._id + '-item'"
:run="run"
:link="true"
:can-exec="canExec"
/>
</template>
</template>
</v-list>
</v-card>
</template>
indeed, eslint-plugin-vue triggers : <template v-for> key should be placed on the <template> tag
but when I change it, it triggers again : '<template v-for>' cannot be keyed. Place the key on real elements instead
I'm perplex
@EDM115 That's not related to this issue.
Your problem is that your eslint config has two rules active that are incompatible.
The first error is from the Vue 3 rule: https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html#vue-no-v-for-template-key-on-child
The second error is from the Vue 2 rule: https://eslint.vuejs.org/rules/no-v-for-template-key.html
So the solution would be to disable one of them - likely the second one as you are on Vue 3 now.