Vue3 各種使用 $refs 取得 DOM 元素技巧

前言

我們在實戰開發上往往都會需要取得 DOM 元素,而這一篇就稍微記錄一下各種使用 $refs 取得 DOM 元素的技巧。

事前說明

由於我這邊範例都是放在 CodePen 上,因此不會使用 script setup 的寫法,只能用 setup return 的髮唷。

基本選取 DOM 方式

初心者剛學 Vue 的時候常見最基本的 DOM 選取方式就是使用原生 JavaScript 的 document.querySelectordocument.getElementById 來選取元素

1
2
3
4
<div id="app">
<div id="box1"></div>
<div class="box2"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const { createApp, onMounted, ref } = Vue;

const app = createApp({
setup() {
onMounted(() => {
const box1 = document.getElementById("box1");
const box2 = document.querySelector(".box2");
console.log('DOM Box1:', box1);
console.log('DOM Box2:', box2);
})
}
});

app.mount('#app');

那麼上面算是基本新手常見在 Vue 中選取 DOM 的方式。

Refs 選取 DOM 元素

接下來就是我們這一篇文章的重點,也就是 refs

refs 是 Vue 提供的一個 API,可以讓我們在 Vue 中選取 DOM 元素,使用方法非常簡單,首先你需要先將你要選取的元素加上 ref 屬性,然後在 setup 中使用 ref 來取得元素(由於我是 setup return 關係,因此必須 return box1 給畫面上使用),這樣子就可以取得 DOM 元素了。

1
2
3
<div id="app">
<div ref="box1"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { createApp, onMounted, ref } = Vue;

const app = createApp({
setup() {
const box1 = ref(null);

onMounted(() => {
console.log('DOM Box1:', box1.value);
})

return {
box1,
}
}
});

app.mount('#app');

上面就是一個最基本的 refs 選取 DOM 元素的方式。

那麼如果今天是一個 v-for 的迴圈呢?該怎麼選取呢?其實也非常簡單

1
2
3
<div id="app">
<div v-for="item in 3" :key="item" ref="box">{{ item }}</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { createApp, onMounted, ref } = Vue;

const app = createApp({
setup() {
const box = ref([]);

onMounted(() => {
console.log('DOM Box:', box.value);
})

return {
box,
}
}
});

app.mount('#app');

這邊我們可以看到 box 是一個陣列,裡面有三個元素,分別是 div 的 DOM 元素。

當然還有別種寫法,就是直接改用動態推入的方式,這邊就要將 ref 改成 v-bind 並寫入一個函式,這樣子就可以動態推入了

1
2
3
<div id="app">
<div v-for="item in 3" :key="item" :ref="(el) => box.push(el)">{{ item }}</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { createApp, onMounted, ref } = Vue;

const app = createApp({
setup() {
const box = ref([]);

onMounted(() => {
console.log('DOM Box:', box.value);
})

return {
box,
}
}
});

app.mount('#app');

而上面這種方式就是一個動態傳入的技巧。

當然你也可以搭配物件來去動態管理到同一個物件下

1
2
3
<div id="app">
<div v-for="item in data" :key="item" :ref="(el) => box[item.name] = el">{{ item }}</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const { createApp, onMounted, ref } = Vue;

const app = createApp({
setup() {
const data = ref([
{ id: 1, name: "apple" },
{ id: 2, name: "banana" },
{ id: 3, name: "orange" },
]);
const box = ref({
apple: null,
banana: null,
orange: null,
});

onMounted(() => {
console.log('DOM Box:', box.value);
})

return {
data,
box,
}
}
});

app.mount('#app');

以上差不多就是 ref 常見的寫法了。