Subscribe on changes!

Template Refs in v-for not working

avatar
Mar 5th 2022

Version

3.2.31

Reproduction link

stackblitz.com

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

avatar
Mar 6th 2022

sfc playground

this works in playground, and "prod" build but fails in vite/vue dev build

avatar
Mar 6th 2022

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

avatar
Mar 7th 2022

duplicate of #5447

avatar
Mar 8th 2022

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.

avatar
Mar 8th 2022

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

Have you solved this problem? How to solve it

avatar
Mar 8th 2022

@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.

avatar
Mar 8th 2022

@lidlanca我打开以进行进一步评估,但并没有真正看到与#5447的区别?#5447也只在 prod/playground 中工作,这是因为渲染函数内联。

Expect to get feedback on this problem, in the process of writing business code, stuck in this piece

avatar
Mar 8th 2022

@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

avatar
Mar 8th 2022

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.

avatar
Mar 8th 2022

@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

avatar
Mar 9th 2022

Same problem :( , hope this bug is fixed soon.

avatar
Mar 9th 2022

@lidlanca Thank you very much for your method, as far as I am concerned, there is no problem now. good good

avatar
Mar 25th 2022

Workaround works 👍🏼 Looking forward to bug fix. Tx

avatar
Apr 6th 2022

Same issue here, thank you for the workaround waiting for the fix. 👍

avatar
Apr 7th 2022

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.

avatar
May 31st 2022

it's still works only with wrapper...

var itemRefs = ref( [] )
var skipUnwrap = { itemRefs }


div(
   v-for=" i in ls " :ref=" skipUnwrap.itemRefs "
  )
avatar
Jul 6th 2022

same problem. Still only works with wrapper

avatar
Jul 6th 2022

not working for me as well

avatar
Jul 7th 2022

@Sven89 @vervelover this because $setup.itemRefs(DEV) and itemRefs.value(PROD) both are Proxy values.

as a workaround.

avatar
Jul 7th 2022

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?

avatar
Jul 7th 2022

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.

avatar
Jul 7th 2022

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

avatar
Jul 7th 2022

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.

avatar
Jul 8th 2022

@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="".

avatar
Jan 25th 2023

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?

avatar
Jan 27th 2023

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.

avatar
Jan 27th 2023

@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.

avatar
Feb 5th 2023

@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.

ref-build

avatar
Feb 5th 2023

@liulinboyi any special configs options used there?

avatar
Feb 6th 2023

@liulinboyi any special configs options used there?

The repository is here.