Vue ref 使用学习笔记

张开发
2026/4/17 20:12:33 15 分钟阅读

分享文章

Vue ref 使用学习笔记
1. 什么是 refref是 Vue 中的一个特殊 attribute用于给元素或子组件注册引用信息。引用信息会被注册在父组件的$refs对象上。核心作用DOM 元素访问在普通 DOM 元素上使用时引用指向 DOM 元素本身组件实例访问在子组件上使用时引用指向组件的实例重要特性ref是作为渲染结果被创建的在初始渲染时不能访问此时还不存在$refs不是响应式的不应该在模板中做数据绑定在使用v-for时引用会是一个包含 DOM 节点或组件实例的数组2. 基本用法2.1 在组合式 API 中使用Vue 3.5使用useTemplateRef()辅助函数script setup import { useTemplateRef, onMounted } from vue // 第一个参数必须与模板中的 ref 值匹配 const input useTemplateRef(my-input) onMounted(() { input.value.focus() }) /script template input refmy-input / /template2.2 在组合式 API 中使用Vue 3.5 前script setup import { ref, onMounted } from vue // 声明一个 ref 来存放该元素的引用 // 必须和模板里的 ref 同名 const input ref(null) onMounted(() { input.value.focus() }) /script template input refinput / /template2.3 在选项式 API 中使用script export default { mounted() { this.$refs.input.focus() } } /script template input refinput / /template3. 具体应用场景3.1 操作 DOM 元素场景在组件挂载后自动聚焦到输入框script setup import { ref, onMounted } from vue const inputRef ref(null) onMounted(() { inputRef.value.focus() }) /script template input refinputRef placeholder请输入内容 / /template3.2 访问子组件实例场景父组件调用子组件的方法!-- Child.vue -- script setup import { ref } from vue const count ref(0) const increment () { count.value } // 暴露方法给父组件 defineExpose({ increment, count }) /script template div子组件计数{{ count }}/div /template!-- Parent.vue -- script setup import { ref, onMounted } from vue import Child from ./Child.vue const childRef ref(null) onMounted(() { // 调用子组件的方法 childRef.value.increment() console.log(子组件计数:, childRef.value.count) }) /script template Child refchildRef / /template3.3 处理 v-for 中的引用场景获取一组 DOM 元素或组件实例script setup import { ref, onMounted } from vue const itemRefs ref([]) onMounted(() { // itemRefs.value 是一个包含所有 li 元素的数组 console.log(itemRefs.value.length) // 访问第一个元素 if (itemRefs.value[0]) { itemRefs.value[0].style.color red } }) /script template ul li v-foritem in 5 :keyitem refitemRefs 项目 {{ item }} /li /ul /template4. 注意事项4.1 引用的生命周期挂载前ref值为null挂载后ref值为 DOM 元素或组件实例卸载后ref值为null例如通过v-if控制4.2 响应式处理如果需要监听引用的变化应考虑到其值为null的情况script setup import { ref, watchEffect } from vue const inputRef ref(null) watchEffect(() { if (inputRef.value) { inputRef.value.focus() } else { // 元素未挂载或已卸载 console.log(元素未就绪) } }) /script4.3 组件暴露控制使用script setup的组件默认是私有的需要通过defineExpose显式暴露属性和方法使用选项式 API 的组件可以通过expose选项限制可访问的属性和方法// 选项式 API 中限制暴露 export default { expose: [publicData, publicMethod], data() { return { publicData: foo, privateData: bar } }, methods: { publicMethod() { /* ... */ }, privateMethod() { /* ... */ } } }5. 类型标注TypeScript5.1 为 DOM 元素标注类型script setup langts import { ref, onMounted } from vue const inputRef refHTMLInputElement | null(null) onMounted(() { inputRef.value?.focus() }) /script5.2 为组件标注类型script setup langts import { ref, onMounted } from vue import Child from ./Child.vue const childRef refInstanceTypetypeof Child | null(null) onMounted(() { childRef.value?.increment() }) /script6. 最佳实践优先使用 props 和 emit大多数情况下应该使用标准的 props 和 emit 接口来实现父子组件交互仅在必要时使用 refref 会创建父子组件之间的紧密耦合应谨慎使用避免在模板中使用 $refs$refs 不是响应式的不适合在模板中进行数据绑定合理处理 null 值在访问 ref 的值时始终考虑其可能为 null 的情况使用 TypeScript 类型标注提高代码的可维护性和类型安全性7. 常见问题与解决方案7.1 问题ref 值为 undefined原因在组件初始渲染时访问 ref此时元素还未挂载解决方案在onMounted生命周期钩子中访问 ref或使用watchEffect监听 ref 的变化7.2 问题v-for 中 ref 不是数组原因在某些 Vue 版本中v-for 中的 ref 需要特殊处理解决方案使用函数式 ref 或确保正确的 ref 赋值方式template ul li v-foritem in 5 :keyitem :refel el itemRefs.push(el) 项目 {{ item }} /li /ul /template7.3 问题无法访问子组件的方法原因子组件使用了script setup但未通过defineExpose暴露方法解决方案在子组件中使用defineExpose显式暴露需要访问的属性和方法8. 总结ref是 Vue 中用于直接访问 DOM 元素和组件实例的强大工具合理使用可以简化某些场景下的开发工作。但需要注意其使用时机和最佳实践避免过度依赖导致代码耦合度增加。通过本文的学习你应该掌握了ref的基本概念和作用在不同 API 风格中的使用方法各种应用场景的具体实现注意事项和最佳实践常见问题的解决方案

更多文章