Vue3 模板引用
一、模板引用基础概念
模板引用是 Vue3 中直接访问 DOM 元素或子组件实例的特殊机制,通过 ref
属性实现。与 Vue2 不同,Vue3 的组合式 API 提供了更灵活的引用方式。
1.1 基本用法
<template>
<input ref="myInput" type="text">
</template>
<script setup>
import { ref, onMounted } from 'vue'
// 声明与模板中 ref 同名的响应式引用
const myInput = ref(null)
onMounted(() => {
myInput.value.focus() // 挂载后自动聚焦输入框
})
</script>
特性说明:
- 引用变量名必须与模板中的
ref
属性值完全匹配 - 通过
.value
访问 DOM 元素(组合式 API 特性) - 必须在
onMounted
生命周期后才能访问引用
二、动态引用进阶技巧
2.1 动态引用名称
通过函数式语法实现动态绑定:
<template>
<div v-for="item in 5" :key="item">
<div :ref="(el) => setItemRef(el, item)">
Item {{ item }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const itemRefs = ref([])
const setItemRef = (el, index) => {
if (el) itemRefs.value[index] = el
}
</script>
注意事项:
- v-for 中的引用会生成数组,但顺序不保证与数据源一致
- 动态引用函数会在每次 DOM 更新时调用
2.2 组件引用
访问子组件实例:
<!-- 父组件 -->
<template>
<ChildComponent ref="childRef" />
</template>
<script setup>
import { ref } from 'vue'
const childRef = ref(null)
</script>
<!-- 子组件 ChildComponent.vue -->
<script setup>
import { ref, defineExpose } from 'vue'
const internalData = ref('secret')
const publicMethod = () => console.log('暴露的方法')
// 必须显式暴露才能被父组件访问
defineExpose({
publicMethod
})
</script>
三、常见应用场景
3.1 表单焦点管理
<template>
<form @submit.prevent="handleSubmit">
<input ref="emailInput" type="email">
<button>提交</button>
</form>
</template>
<script setup>
const emailInput = ref(null)
const handleSubmit = () => {
if (!emailInput.value.value) {
emailInput.value.focus()
}
}
</script>
3.2 第三方库集成
<template>
<div ref="chartContainer"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
const chartContainer = ref(null)
let chartInstance = null
onMounted(() => {
chartInstance = echarts.init(chartContainer.value)
// 初始化图表...
})
onUnmounted(() => {
chartInstance?.dispose()
})
</script>
四、常见问题与解决方案
4.1 引用值为 null
原因:在组件挂载前访问引用
解决:使用 onMounted
生命周期钩子
4.2 动态组件引用丢失
现象:切换动态组件时引用失效
解决:使用函数式引用绑定
<template>
<component :is="currentComponent" :ref="setDynamicRef">
</template>
<script setup>
const dynamicRef = ref(null)
const setDynamicRef = (el) => {
dynamicRef.value = el
}
</script>
4.3 TypeScript 类型定义
// DOM 元素类型
const inputRef = ref<HTMLInputElement | null>(null)
// 组件类型
const childRef = ref<InstanceType<typeof ChildComponent> | null>(null)
五、最佳实践建议
- 最小化 DOM 操作:优先使用 Vue 的声明式语法
- 引用命名规范:使用
xxxRef
后缀提高可读性 - 内存管理:及时清理第三方库实例
- 类型安全:使用 TypeScript 增强类型检查
- 性能优化:避免在模板中频繁创建引用函数
通过掌握这些技巧,您可以更高效地处理需要直接操作 DOM 或组件实例的复杂场景。实际开发中,建议结合 Vue Devtools 进行引用调试。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 万家灯火