How to access dynamically defined ref

I have a component template that looks like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div v-for="thing of someListOfObject">
<div :ref="thing.id">
hi !
</div>
</div>
</code>
<code><div v-for="thing of someListOfObject"> <div :ref="thing.id"> hi ! </div> </div> </code>
<div v-for="thing of someListOfObject">
    <div :ref="thing.id">
       hi !
    </div>
</div>

To access a ref in the script, you should normally do :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><template>
<div ref="test" />
</template>
<script setup>
const test = ref(null)
</script>
</code>
<code><template> <div ref="test" /> </template> <script setup> const test = ref(null) </script> </code>
<template>
    <div ref="test" />
</template>
<script setup>
const test = ref(null)
</script>

The name of the const should be the same name as the ref. But, as my ref is declared from a property, I couldn’t find a way to access it from my script.

I already tried to access child from parents ref like that :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><template>
<div v-for="thing of someListOfObject" ref="things">
<div>
hi !
</div>
</div>
</template>
<script>
const things = ref([])
</script>
</code>
<code><template> <div v-for="thing of someListOfObject" ref="things"> <div> hi ! </div> </div> </template> <script> const things = ref([]) </script> </code>
<template>
   <div v-for="thing of someListOfObject" ref="things">
      <div>
       hi !
      </div>
   </div>
</template>
<script>
const things = ref([])
</script>

And it kinda worked, but in my case, the child element is nested in a bunch of other div so access it from the parent is a real mess.

Any ideas how directly access the nested ref?

2

According to your first snippet you want to fill id prop of the list with DIV references. You can do this with a directive:

Playground

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { ref , reactive} from 'vue'
const someListOfObject = reactive(Array.from({length: 10}, ()=>({})));
const vMount = {
mounted($el, {value: idx}){
someListOfObject[idx].id = $el;
}
}
</script>
<template>
<div>{{someListOfObject}}</div>
<div v-for="(thing, idx) in someListOfObject">
<div v-mount="idx">
hi !
</div>
</div>
</template>
</code>
<code><script setup> import { ref , reactive} from 'vue' const someListOfObject = reactive(Array.from({length: 10}, ()=>({}))); const vMount = { mounted($el, {value: idx}){ someListOfObject[idx].id = $el; } } </script> <template> <div>{{someListOfObject}}</div> <div v-for="(thing, idx) in someListOfObject"> <div v-mount="idx"> hi ! </div> </div> </template> </code>
<script setup>
import { ref , reactive} from 'vue'

const someListOfObject = reactive(Array.from({length: 10}, ()=>({})));

const vMount = {
  mounted($el, {value: idx}){
    someListOfObject[idx].id = $el;
  }
}

</script>

<template>
<div>{{someListOfObject}}</div>
<div v-for="(thing, idx) in someListOfObject">
    <div v-mount="idx">
       hi !
    </div>
</div>
</template>

Although @Nicolas found the answer to their question, I’ll leave a more detailed explanation and clarification here. The documentation he referenced provides a partial answer to the question. The code he wrote is unclear and does not align with the guidelines provided in the documentation.

Vue 3.5 or above (new)

Starting from Vue 3.5, a special ref called templateRef has been introduced. To use it effectively, it is recommended to review the example in the documentation.

When ref is used inside v-for, the corresponding ref should contain an Array value, which will be populated with the elements after mount:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { ref, useTemplateRef, onMounted } from 'vue'
const list = ref([
/* ... */
])
// Declare array for the dynamic collection of refs
// CHANGED: The variable name can differ from the value of the Template element's ref attribute. ---> in my example itemRefs custom-name related to ref="items"
const itemRefs = useTemplateRef('items')
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</template>
</code>
<code><script setup> import { ref, useTemplateRef, onMounted } from 'vue' const list = ref([ /* ... */ ]) // Declare array for the dynamic collection of refs // CHANGED: The variable name can differ from the value of the Template element's ref attribute. ---> in my example itemRefs custom-name related to ref="items" const itemRefs = useTemplateRef('items') onMounted(() => console.log(itemRefs.value)) </script> <template> <ul> <li v-for="item in list" ref="items"> {{ item }} </li> </ul> </template> </code>
<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'

const list = ref([
  /* ... */
])

// Declare array for the dynamic collection of refs
// CHANGED: The variable name can differ from the value of the Template element's ref attribute. ---> in my example itemRefs custom-name related to ref="items"
const itemRefs = useTemplateRef('items')

onMounted(() => console.log(itemRefs.value))
</script>

<template>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</template>

Source: Refs inside v-for

This way, you can dynamically create an array of refs.

In the past, a reactive reference to a Template element could be made with the ref(null) declaration. Previously, there was a strict rule that the name of the declared ref variable had to match the string in the Template element’s ref attribute. From now on, with useTemplateRef('ref-attribute-value'), the variable name is no longer bound by this constraint.

Similarly, to create a dynamic ref array in the past, you had to declare an empty array ref with a strict variable name. Now, you can simply use useTemplateRef paired with v-for.

Use dynamically Template ref-attribute value

The value passed to useTemplateRef can also be dynamic:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { useTemplateRef} from 'vue'
const dynamicName = "inputDynamicRefName"
const input = useTemplateRef(dynamicName)
</script>
<template>
<div>
<input :ref="dynamicName" />
</div>
</template>
</code>
<code><script setup> import { useTemplateRef} from 'vue' const dynamicName = "inputDynamicRefName" const input = useTemplateRef(dynamicName) </script> <template> <div> <input :ref="dynamicName" /> </div> </template> </code>
<script setup>
import { useTemplateRef} from 'vue'

const dynamicName = "inputDynamicRefName"
const input = useTemplateRef(dynamicName)
</script>

<template>
  <div>
    <input :ref="dynamicName" />
  </div>
</template>
  • Accessing the Refs alias useTemplateRef (refer to single Template element) – Vue Docs
  • Refs inside v-for (refer to multiple Template elements by v-for) – Vue Docs

Usage before 3.5 (old)

Previously, you had to declare an empty array of refs, which, when injected alongside a v-for, achieved a similar result.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { ref, useTemplateRef, onMounted } from 'vue'
const list = ref([
/* ... */
])
// Declare array for the dynamic collection of refs
// IMPORTANT: The variable name must strictly match the value of the Template element's ref attribute! ---> itemRefs
const itemRefs = ref([]) // from 3.5 can use useTemplateRef()
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>
</code>
<code><script setup> import { ref, useTemplateRef, onMounted } from 'vue' const list = ref([ /* ... */ ]) // Declare array for the dynamic collection of refs // IMPORTANT: The variable name must strictly match the value of the Template element's ref attribute! ---> itemRefs const itemRefs = ref([]) // from 3.5 can use useTemplateRef() onMounted(() => console.log(itemRefs.value)) </script> <template> <ul> <li v-for="item in list" ref="itemRefs"> {{ item }} </li> </ul> </template> </code>
<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'

const list = ref([
  /* ... */
])

// Declare array for the dynamic collection of refs
// IMPORTANT: The variable name must strictly match the value of the Template element's ref attribute! ---> itemRefs
const itemRefs = ref([]) // from 3.5 can use useTemplateRef()

onMounted(() => console.log(itemRefs.value))
</script>

<template>
  <ul>
    <li v-for="item in list" ref="itemRefs">
      {{ item }}
    </li>
  </ul>
</template>

Source: Refs inside v-for

Use dynamically Template ref-attribute value

Essentially, after creating an object, we can add the element obtained through the ref attribute as a property of that object.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { reactive } from 'vue'
const dynamicName = "inputDynamicRefName"
const inputs = reactive({})
// It has nothing to do with the new useTemplateRef; I named it similarly only because of the similar functionality
const setTemplateRef = (key, el) => {
inputs[key] = el
}
</script>
<template>
<div>
<input :ref="(el) => setTemplateRef(dynamicName, el)" />
</div>
</template>
</code>
<code><script setup> import { reactive } from 'vue' const dynamicName = "inputDynamicRefName" const inputs = reactive({}) // It has nothing to do with the new useTemplateRef; I named it similarly only because of the similar functionality const setTemplateRef = (key, el) => { inputs[key] = el } </script> <template> <div> <input :ref="(el) => setTemplateRef(dynamicName, el)" /> </div> </template> </code>
<script setup>
import { reactive } from 'vue'

const dynamicName = "inputDynamicRefName"
const inputs = reactive({})

// It has nothing to do with the new useTemplateRef; I named it similarly only because of the similar functionality
const setTemplateRef = (key, el) => {
  inputs[key] = el
}
</script>

<template>
  <div>
    <input :ref="(el) => setTemplateRef(dynamicName, el)" />
  </div>
</template>

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script setup>
import { reactive, onMounted } from 'vue'
const things = reactive({})
const setTemplateRef = (id, el) => {
things[id] = el
}
onMounted(() => {
console.log(things.value)
})
</script>
<template>
<div v-for="(thing, index) in someListOfObject" :key="thing.id">
<div :ref="(el) => setTemplateRef(thing.id, el)">
hi!
</div>
</div>
</template></code>
<code><script setup> import { reactive, onMounted } from 'vue' const things = reactive({}) const setTemplateRef = (id, el) => { things[id] = el } onMounted(() => { console.log(things.value) }) </script> <template> <div v-for="(thing, index) in someListOfObject" :key="thing.id"> <div :ref="(el) => setTemplateRef(thing.id, el)"> hi! </div> </div> </template></code>
<script setup>
import { reactive, onMounted } from 'vue'

const things = reactive({})

const setTemplateRef = (id, el) => {
  things[id] = el
}

onMounted(() => {
  console.log(things.value)
})
</script>

<template>
  <div v-for="(thing, index) in someListOfObject" :key="thing.id">
    <div :ref="(el) => setTemplateRef(thing.id, el)">
      hi!
    </div>
  </div>
</template>
  • Function Refs alias :ref="(el) => ..." (refer to single Template element by ref function)

The solution is to use useTemplateRef:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><template>
<div v-for="thing of someListOfObject" ref="things">
<div>
hi !
</div>
</div>
</template>
<script setup>
import { useTemplateRef, onMounted } from 'vue'
for(thing in someListOfObject){
console.log(useTemplateRef(thing.id))
}
</script>
</code>
<code><template> <div v-for="thing of someListOfObject" ref="things"> <div> hi ! </div> </div> </template> <script setup> import { useTemplateRef, onMounted } from 'vue' for(thing in someListOfObject){ console.log(useTemplateRef(thing.id)) } </script> </code>
<template>
   <div v-for="thing of someListOfObject" ref="things">
      <div>
       hi !
      </div>
   </div>
</template>

<script setup>
import { useTemplateRef, onMounted } from 'vue'

for(thing in someListOfObject){
  console.log(useTemplateRef(thing.id))
}
</script>

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật