添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working

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

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

@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

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

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.

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

nothing is working and gives me headache omg. The value of ref, no matter what i do (skip unwrap, binding with function and push), is a proxy and I can't access anything. When i try to access with myArray.value[0], it gives undefined

Can you provide a minimum reproduction? Thanks.

Also spent a bit of time on this, the way it works for me:

<script setup>
const items = ['i1', 'i2', 'i3'];
const elRefs = reactive([]);
function updateRefs(el, index) {
  elRefs[index] = el;
</script>
<template>
    <div v-for="item, index in items" :key="index"
             :ref="(el) => getPlayerRef(el, index)">
    {{ item }}
    </div>
  </div>
</template>

Also works with components and exposing function on these components.

Also spent a bit of time on this, the way it works for me:

<script setup>
const elRefs = reactive([]);
function updateRefs(el) {
  elRefs[index] = el;
</script>
<template>
    <div v-for="i in 5" :key="i" :ref="updateRefs">
    {{ i }}
</template>

Also works with components and exposing function on these components.

Hey @Seanitzel

Where do you get the index inside your updateRefs from?

❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working