在原生的 JavaScript 中要取得 DOM 元素需要類似這樣的語法,以取得 id 為 div1 的 DOM 元素:
var div1 = document.getElementById('div1');如果是在 VUE,要在 Composition API 的語意環境中取得 DOM 元素,則必須在 DOM 元素放一個 ref=”xxx” 來取代 id,並宣告一個與 xxx 同名的 ref,指向那個 DOM 元素,以進行進一步的操作:

要注意的是:template ref (模板引用)在 mounted 之前為 null,要在 mounted 之後才能取得 template ref(模板引用) 的值,這是因為 DOM 元素在 Mounted 之後才會掛載在網頁上。
<script setup>
import { ref, onMounted } from 'vue'
// 宣告一個 ref 來存放該元素的引用
// 必須和 <template> 的元素同名
const input = ref(null)
console.log('before Mounted',input.value)
// null
onMounted(() => {
console.log('after Mounted',input.value)
input.value.focus()
// <input>
})
</script>
<template>
<input ref="input" />
</template>v-for 跟 ref 的關係
如果想要取得 v-for 的 DOM 元素,它所對應的 ref 值會是一個陣列,陣列裡會有 v-for 渲染出來的所有 DOM 元素。
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([1, 2, 3])
const itemRefs = ref([])
onMounted(() => {
console.log(itemRefs.value)
})
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>如下圖所見,console 出來的結果是一個陣列中放著 3 個 li。

ref 在元件上使用
App.vue
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
const child = ref(null)
onMounted(() => {
// child.value will hold an instance of <Child />
console.log(child)
})
</script>
<template>
<Child ref="child" />
</template>Child.vue
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
// Compiler macros, such as defineExpose, don't need to be imported
defineExpose({
a,
b
})
</script>當我們在父元件置入子元件時,放入 ref=”child”。
<Child ref="child" />並且建立一個 child 常數,賦予它一個 null 的 ref,就可以透過 ref 取得以物件型態表現的子元件。
const child = ref(null)比較特別的是在 setup function中,要多寫 defineExpose({}),子元件內部的資料才能讓父元件取得。
defineExpose({
a,
b
})如下圖,在 mounted 時 console.log(child),可以看到 child 子元件內部所擁有的資料。

最後要注意的是:如果要讓父元件能夠響應式地取得子元件內部資料的變化,還是要透過 props 和 emits。
參考資料:
