0

I'm creating a library and I do renderless components that just renders whatever is in slots. For the purpose of demonstration, I added dummy VNodes array instead.

<template>
    <component
      v-for="vnode of vnodes"
      :key="vnode.toString()"
      :is="vnode"
      ref="elements"
    />
</template>

<script setup>
import { ref, h, onMounted } from "vue";

const elements = ref([]);

const vnodes = [
  h(
    "div",
    {
      class: "foo"
    },
    "Hello One!"
  ),
  h(
    "div",
    {
      class: "bar"
    },
    "Hello Two!"
  )
];

onMounted(() => {
  console.log(elements.value[0]); 
// expected: First element of array (Element)
// reality: undefined
});
</script>

CodePen repro

In my use case, I fetch VNodes from slots and then rendering it via <component> in template. It renders properly, however I can't get the references to rendered elements at onMounted(). Does anyone know what's wrong with this approach, or is it a Vue bug?

6
  • what version of vue are you using? Commented Apr 25, 2022 at 13:24
  • It's Vue 3.2.31 Commented Apr 25, 2022 at 13:28
  • So I've tried exactly the code you provided in exactly the version you mentioned and it works just fine (I used sfc.vuejs.org for testing it). Are you sure the error is not due to the fetch of the nodes? Commented Apr 25, 2022 at 13:31
  • Yeah I'm trying it in SFC vuejs and it's working. Weirdly, in CodePen it's not (they are using the latest one, 3.2.31) Commented Apr 25, 2022 at 13:44
  • Did the provided answer help? or are you still looking for a solution? Commented Apr 26, 2022 at 11:05

1 Answer 1

1

I have tried it in codepen and I also think this is how you should do it in vue 3. (best practice as of Vue.js version 3)

Functional Template Refs

:ref="(el) => elements.push(el)"

instead of

ref="elements"

If you face issues with duplicates in the array you might have to reset the array in a vue lifecycle hooks

Sign up to request clarification or add additional context in comments.

4 Comments

This will create duplicate elements on each update cycle.
@MartinZeltin as stated in the last part of sentence, you have to reset the array in a lifecycle hook.
If you have a unique id or index available you can also do this to avoid duplication :ref="(el) => myElements[id] = el"
@MartinZeltin you could edit my answer so it's included and I'm not pretending it is my answer (or my edit) :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.