Vue 3 模板引用(Template Refs)詳解與實戰示例
引言
在 Vue 開發中,通常推薦使用 響應式數據 (ref
和 reactive
) 進行數據綁定,而不是直接操作 DOM。但是,在某些情況下,我們確實需要訪問某個組件或 DOM 元素,這時候就可以使用 模板引用(Template Refs)。
本篇文章將詳細介紹 Vue 3 的 ref
模板引用的用法、適用場景,并通過多個示例展示如何在 Vue 組件中高效操作 DOM 和組件實例。
1. 什么是 Vue 模板引用?
模板引用(Template Refs) 允許我們在 Vue 組件的模板中標記一個 DOM 元素或子組件,并在 setup
選項中訪問它。
基本語法
<template><div ref="myDiv">Hello Vue!</div>
</template><script setup>
import { ref, onMounted } from 'vue';const myDiv = ref(null); // 定義模板引用onMounted(() => {console.log(myDiv.value); // 獲取 DOM 元素
});
</script>
說明:
ref="myDiv"
綁定到myDiv
變量onMounted
鉤子確保myDiv.value
在 DOM 渲染完成后可用
2. 模板引用的使用場景
? 操作原生 DOM
當我們需要手動操作 DOM 時,如獲取元素的寬高、設置焦點等:
<template><input ref="inputRef" type="text" placeholder="輸入內容"><button @click="focusInput">聚焦輸入框</button>
</template><script setup>
import { ref } from 'vue';const inputRef = ref(null);const focusInput = () => {inputRef.value.focus(); // 手動聚焦輸入框
};
</script>
? 獲取子組件實例
可以使用 ref
訪問子組件的方法和數據:
<!-- 子組件 (Child.vue) -->
<template><div>子組件</div>
</template><script setup>
import { ref } from 'vue';const message = ref("Hello from Child Component!");const sayHello = () => {console.log(message.value);
};defineExpose({ sayHello }); // 允許父組件訪問 `sayHello`
</script>
<!-- 父組件 -->
<template><Child ref="childRef" /><button @click="callChildMethod">調用子組件方法</button>
</template><script setup>
import { ref, onMounted } from 'vue';
import Child from './Child.vue';const childRef = ref(null);onMounted(() => {console.log(childRef.value); // 獲取子組件實例
});const callChildMethod = () => {childRef.value.sayHello(); // 調用子組件方法
};
</script>
defineExpose
:Vue 3 需要使用defineExpose
公開組件方法,否則父組件無法訪問。
3. 使用 ref
訪問多個元素
當我們需要訪問 多個 DOM 元素時,可以使用 ref
結合 v-for
:
<template><div v-for="(item, index) in list" :key="index" ref="itemRefs">{{ item }}</div><button @click="logElements">查看所有元素</button>
</template><script setup>
import { ref, onMounted } from 'vue';const list = ref(["Vue", "React", "Angular"]);
const itemRefs = ref([]); // 存儲多個 DOM 元素onMounted(() => {console.log(itemRefs.value); // 所有 div 的 DOM 元素
});const logElements = () => {itemRefs.value.forEach(el => console.log(el.textContent));
};
</script>
注意:
ref
數組會在onMounted
之后才填充值。
4. 訪問 setup()
之外的數據
如果你在 setup()
之外使用 ref
,可以通過 getCurrentInstance()
獲取 Vue 實例:
<script setup>
import { getCurrentInstance, onMounted } from 'vue';onMounted(() => {const instance = getCurrentInstance();console.log(instance.refs); // 訪問 ref
});
</script>
5. 結論
Vue 3 的 模板引用(Template Refs) 讓我們可以更方便地訪問 DOM 和子組件實例,適用于:
- 操作原生 DOM(如獲取焦點、測量元素尺寸)
- 調用子組件方法(通過
ref
和defineExpose
) - 獲取多個元素(使用
ref
數組)
但是,如果能用 Vue 的 響應式數據 來實現同樣的效果,最好避免直接操作 DOM,以保持 Vue 響應式系統的優勢。