1. Vue 2 与 Vue 3 中的 ref 核心概念解析
ref 是 Vue 响应式系统的核心 API 之一,它在 Vue 2 和 Vue 3 中有着不同的实现机制和使用方式。理解 ref 的工作原理,对于开发高效、可维护的 Vue 应用至关重要。
1.1 ref 的本质与作用
ref(reference 的缩写)在 Vue 中主要有两个用途:
- 获取 DOM 元素或组件实例的引用
- 创建响应式的基本数据类型变量
在 Vue 2 中,我们主要通过 this.$refs 来访问模板引用,而响应式数据则通过 data 选项声明。Vue 3 引入了组合式 API 后,ref API 统一了这两种用途。
javascript复制// Vue 2 中的模板引用
<template>
<div ref="myDiv"></div>
</template>
<script>
export default {
mounted() {
console.log(this.$refs.myDiv) // 获取DOM引用
}
}
</script>
// Vue 3 中的ref用法
<template>
<div ref="myDiv"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const myDiv = ref(null)
onMounted(() => {
console.log(myDiv.value) // 获取DOM引用
})
</script>
1.2 Vue 2 与 Vue 3 响应式实现的差异
Vue 2 使用 Object.defineProperty 实现响应式,这种方式有几个限制:
- 无法检测对象属性的添加或删除
- 对数组的变化检测需要通过特殊方法(如 push、pop 等)
- 性能开销较大,因为需要递归遍历所有属性
Vue 3 改用 Proxy 实现响应式,带来了以下改进:
- 可以检测到属性的添加和删除
- 支持 Map、Set 等新的集合类型
- 性能更好,惰性处理嵌套对象
javascript复制// Vue 2 的响应式实现(简化版)
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`get ${key}:${val}`)
return val
},
set(newVal) {
console.log(`set ${key}:${newVal}`)
val = newVal
}
})
}
// Vue 3 的响应式实现(简化版)
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log(`get ${key}:${target[key]}`)
return target[key]
},
set(target, key, value) {
console.log(`set ${key}:${value}`)
target[key] = value
return true
}
})
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Vue 3 中 ref 的深度解析
2.1 ref 的基本用法
在 Vue 3 的组合式 API 中,ref 用于创建响应式的基本数据类型(string、number、boolean等)。它返回一个带有 value 属性的响应式对象。
javascript复制import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
在模板中使用 ref 时,Vue 会自动解包,不需要写 .value:
html复制<template>
<button @click="count++">
{{ count }} <!-- 自动解包,不需要count.value -->
</button>
</template>
2.2 ref 的响应式原理
ref 的实现可以简化为以下伪代码:
javascript复制function ref(value) {
const refObject = {
get value() {
track(refObject, 'value') // 依赖收集
