1. 理解 ref 在 Vue 中的双重角色
在 Vue 的世界里,ref 这个看似简单的概念实际上扮演着两个截然不同却又紧密相关的角色。这种双重身份常常让初学者感到困惑,但一旦理解清楚,就能在开发中游刃有余。
1.1 模板引用:DOM 元素的直接访问
作为模板引用时,ref 是 Vue 提供的一种特殊属性,允许我们在组件中直接访问 DOM 元素或子组件实例。这在需要直接操作 DOM 的场景下非常有用,比如:
html复制<template>
<input ref="usernameInput" type="text" />
</template>
<script>
export default {
mounted() {
this.$refs.usernameInput.focus() // 页面加载后自动聚焦输入框
}
}
</script>
这种用法在 Vue 2 和 Vue 3 中基本保持一致,但 Vue 3 的 Composition API 引入后,我们有了更灵活的使用方式:
javascript复制import { ref, onMounted } from 'vue'
export default {
setup() {
const usernameInput = ref(null)
onMounted(() => {
usernameInput.value.focus()
})
return { usernameInput }
}
}
重要提示:模板引用的
ref只在组件渲染完成后才可用,在setup()或created生命周期中访问会是null。
1.2 响应式数据:基本类型的包装器
ref 的第二个角色是作为响应式数据的包装器,这是 Vue 3 的 Composition API 引入的核心概念之一。它的主要作用是让基本类型(如字符串、数字、布尔值)也能具备响应性:
javascript复制import { ref } from 'vue'
const count = ref(0) // 创建一个响应式的数字
console.log(count.value) // 0
count.value++ // 修改值会触发响应式更新
在 Vue 2 中,我们通常使用 data() 返回对象来实现响应式:
javascript复制export default {
data() {
return {
count: 0
}
}
}
Vue 3 的 ref 解决了 Vue 2 中必须将基本类型包装在对象中才能实现响应式的问题,提供了更灵活的数据管理方式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Vue 2 中的 ref 实现与使用
2.1 模板引用的实现机制
在 Vue 2 中,ref 主要通过 $refs 对象来工作。当你在模板中使用 ref 属性时:
html复制<div ref="myDiv">Hello World</div>
Vue 会在组件实例上创建一个 $refs 对象,并在组件挂载后将对应的 DOM 元素或组件实例赋值给它:
javascript复制mounted() {
console.log(this.$refs.myDiv) // 输出对应的 DOM 元素
}
值得注意的是,$refs 不是响应式的,因此不应该在模板中依赖它进行数据绑定。它主要用于 JavaScript 直接操作。
2.2 响应式数据的替代方案
Vue 2 本身没有 ref 函数的概念,要实现类似功能,我们通常使用 data 属性:
javascript复制export default {
data() {
return {
count: 0
}
},
