Template Refs in v-for not working
Version
3.2.31
Reproduction link
Steps to reproduce
Open the DevTools and look at the console.logs from onMounted
.
You now see three logs, each representing a different template Ref.
Log one and three are a single template ref and an array filled with function refs. They are working fine as expected.
The issue is that the second ref is not returning an array of elements from the v-for
but stays empty as initialized.
What is expected?
Template Ref on the v-for
should be a DOM NodeList or an Array of DOMElements
What is actually happening?
The initialized ref([])
stays empty
this works in playground, and "prod" build but fails in vite/vue dev build
I have the same problem too, and i can give another repro case here, the template refs
in devtools seems to be a different thing than the references given in script setup
. I tried to use function refs but the callback typings seems to be broken and the el
param gets evaluated in typescript as any
. so vue-tsc or other typechecking solutions will fail under it's usage. The only way i managed to access the template refs without much headache but more verbosity is to access $refs
directly into the template, and either execute or pass the value or callback in the template
not a duplicate of #5447
see repro in my comment above the same code doesn't work in vite dev build.
there is a different code generation between dev and prod.
I have the same problem too, and i can give another repro case here, the
template refs
in devtools seems to be a different thing than the references given inscript setup
. I tried to use function refs but the callback typings seems to be broken and theel
param gets evaluated in typescript asany
. so vue-tsc or other typechecking solutions will fail under it's usage. The only way i managed to access the template refs without much headache but more verbosity is to access$refs
directly into the template, and either execute or pass the value or callback in the template
Have you solved this problem? How to solve it
@lidlanca i opened for further evaluation but don't really see the difference to #5447 ? #5447 also only worked in prod/playground, and that's because of the render function inlining.
@lidlanca我打开以进行进一步评估,但并没有真正看到与#5447的区别?#5447也只在 prod/playground 中工作,这是因为渲染函数内联。
Expect to get feedback on this problem, in the process of writing business code, stuck in this piece
@LinusBorg
I didnt realize #5447 was dev / prod build sensetive.
In that case this issue does share a common root cause.
However i am not sure my pr covers the dev build case. The Ref are not normalized to even hit the fix code path
I'd have to take a closer look, but in dev, the ref would be part of setupState
so it seemed to me your change would fix the problem.
@LinusBorg ignore this
The Ref are not normalized to even hit the fix code path that was due to a
:
binding on the ref when I tested.
The PR does indeed fix this issue for dev mode!
A possible workaround for the current limitation is:
<script setup>
import { ref, computed, onMounted } from 'vue';
//escapse template unwrapping
const skipUnwrap = { el: ref([]) };
// for convenience
let el = computed(() => skipUnwrap.el.value);
onMounted(() => {
console.log(el.value);
});
</script>
<template>
<div>
<div v-for="i in 'hello'" :key="i" :ref="skipUnwrap.el">{{ i }}</div>
Total Refs: {{ el.length }}
</div>
</template>
https://stackblitz.com/edit/vitejs-vite-jfeskg?file=src/App.vue
@lidlanca Thank you very much for your method, as far as I am concerned, there is no problem now. good good
I'll add my name to the list of people affected by this. I am converting a mid-sized app to the composition API and this breaks some core functionality. I'll try the workaround, but it seems shaky.
it's still works only with wrapper...
var itemRefs = ref( [] )
var skipUnwrap = { itemRefs }
div(
v-for=" i in ls " :ref=" skipUnwrap.itemRefs "
)
@Sven89 @vervelover
this because $setup.itemRefs
(DEV) and itemRefs.value
(PROD) both are Proxy
values.
as a workaround.
Hi, thank you for the answer, unfortunately all workarounds posted seem to add values to the ref array, but contrary to what I was able to do in vue 2, in vue 3 I cannot access any method defined on the ref. So let's say I have a validate()
method on the first ref of the itemRefs array, in vue 2 I was able to call it like this:
itemRefs.value[0].validate()
But how do I call the method in vue 3 Proxy
values?
Hi, thank you for the answer, unfortunately all workarounds posted seem to add values to the ref array, but contrary to what I was able to do in vue 2, in vue 3 I cannot access any method defined on the ref. So let's say I have a
validate()
method on the first ref of the itemRefs array, in vue 2 I was able to call it like this:
itemRefs.value[0].validate()
But how do I call the method in vue 3
Proxy
values?
Use defineExpose()
😉, docs.
Use defineExpose()wink, docs.
That was awesome, thank you!
I still do not understand why this bug is closed though, because I still get an empty array of refs when not using the object wrap workaround..
After I updated with the version that fixed it, I was able to remove the workaround and ref worked properly again. Unless there was another regression, I can attest to the bug having been fixed.
@vervelover
:ref="itemRefs"
value only support string, ref, function
.
itemRefs
in template will be compiled to $setup.itemRefs(in DEV) or itemRefs.value(in PROD)
it unwrap into a Proxy
value. so this is a limitaion for directly use a ref in :ref=""
.
I experienced this issue yesterday in the newest Vue version. Only in Vite build not in Vite dev.
With the wrapper it worked in both. So this issue is still relevant?
I experienced this issue yesterday in the newest Vue version. Only in Vite build not in Vite dev.
With the wrapper it worked in both. So this issue is still relevant?
Can you provide a minimum reproduction? Thanks.
@liulinboyi
This is a simplified example: https://stackblitz.com/edit/vitejs-vite-bqescg?file=src/App.vue
Works fine in dev but not once it is builded.
@liulinboyi
This is a simplified example: stackblitz.com/edit/vitejs-vite-bqescg?file=src/App.vue
Works fine in dev but not once it is builded.
I have download stackblitz.com/edit/vitejs-vite-bqescg?file=src/App.vue to local and build use Vite, but it will also work fine.
@liulinboyi any special configs options used there?
The repository is here.