2026-10-31 17:01:34
在 Vue.js 中,$refs 是一个用于访问模板中通过 ref 属性标记的 DOM 元素或子组件实例的机制。它提供了一种直接操作 DOM 或子组件的方法,但需谨慎使用以避免破坏 Vue 的响应式原则。以下是关于 $refs 的详细说明:
1. 基本用法获取 DOM 元素:在模板中为元素添加 ref 属性,通过 this.$refs.refName 访问。
<template> <input ref="inputRef" type="text" /></template><script>export default { mounted() { this.$refs.inputRef.focus(); // 直接操作 DOM }};</script>获取子组件实例:若 ref 用于子组件,$refs 指向子组件的 Vue 实例,可调用其方法或访问数据。
<template> <ChildComponent ref="childRef" /></template><script>export default { methods: { callChildMethod() { this.$refs.childRef.someMethod(); // 调用子组件方法 } }};</script>响应性限制:$refs 不是响应式的,避免在模板或计算属性中使用它,否则可能导致不可预期的行为。
渲染时机:$refs 仅在组件渲染完成后填充,不可在 created 钩子中访问(此时 DOM 未生成),应在 mounted 或之后使用。
动态 ref:若 ref 绑定到 v-for 循环中的元素,$refs 会是数组;动态绑定的 ref(如 :ref="dynamicRef")需确保值唯一。
当 ref 用于循环渲染的元素时,$refs 会成为数组:
<template> <div v-for="item in list" :key="item.id" :ref="setItemRef"> {{ item.text }} </div></template><script>export default { data() { return { list: [{ id: 1, text: 'A' }, { id: 2, text: 'B' }] }; }, methods: { setItemRef(el) { if (el) { // 通过函数收集所有 ref this.$refs.itemRefs = this.$refs.itemRefs || []; this.$refs.itemRefs.push(el); } } }};</script>4. 替代方案与最佳实践优先使用 props 和 events:父子组件通信应通过 props 下传数据、$emit 触发事件,而非直接操作 $refs,以保持组件解耦。
模板引用变量(Vue 3):在 Vue 3 的 <script setup> 中,可使用 ref 函数声明模板引用:
<template> <input ref="inputRef" /></template><script setup>import { ref, onMounted } from 'vue';const inputRef = ref(null);onMounted(() => inputRef.value.focus());</script>避免过度依赖:频繁操作 $refs 可能使代码难以维护,建议仅在必须直接访问 DOM(如集成第三方库)时使用。
$refs 为 undefined:检查是否在渲染完成后访问(如 mounted 而非 created),或确认 ref 名称拼写正确。
动态组件与 ref:动态组件(<component :is="...">)的 ref 需确保组件已加载后再访问。
$refs 是 Vue 中操作 DOM 或子组件的快捷方式,但需遵循其非响应式和渲染时机的特性。合理使用可提升开发效率,但过度依赖可能破坏组件化设计。在 Vue 3 中,推荐使用组合式 API 的 ref 函数替代部分场景。