
一、核心概念与作用
Vue3的响应式系统是其核心亮点之一,通过ref和reactive实现数据变化自动触发视图更新。它们是Composition API中最常用的响应式工具,但用法、适用场景和底层机制存在明显差异。
1.1 ref
- 作用:创建一个响应式的基本数据类型包装对象。
- 语法:
const count = ref(0),通过.value访问或修改数据(模板中自动解包)。 - 适用场景:简单数据、需跨组件传递的独立变量、需要重新赋值的场景(如替换整个对象)。
1.2 reactive
- 作用:创建一个响应式的对象,通过
Proxy实现深度响应式代理。 - 语法:
const state = reactive({ count: 0 }),直接访问属性(如state.count)。 - 适用场景:复杂嵌套对象、需深度响应式追踪的复杂数据结构。

二、核心区别与原理
2.1 数据类型支持
- ref:支持所有JavaScript数据类型(基本类型+引用类型)。
- reactive:仅支持对象类型(对象、数组、Map/Set等)。
2.2 访问与修改方式
- ref:需通过
.value访问(模板中自动解包)。 - reactive:直接访问属性(如
state.count)。
2.3 重新赋值响应性
- ref:重新赋值整个对象/数组(如
list.value = [1,2,3])响应性不会丢。 - reactive:直接替换对象(如
obj = {name: '李四'})响应性失效。
2.4 底层原理
- ref:基于
Object.defineProperty实现数据劫持,通过.value访问内部值。 - reactive:基于
Proxy实现深度响应式代理,直接代理对象属性。

三、实战场景与使用示例
3.1 基本数据类型场景
// 创建响应式数字
const count = ref(0)
count.value++ // 触发视图更新
// 创建响应式字符串
const message = ref('Hello')
message.value = 'World' // 视图自动更新
3.2 对象与数组场景
// 响应式对象
const user = ref({ name: 'Alice' })
user.value.name = 'Bob' // 触发视图更新
// 响应式数组
const items = ref([1, 2, 3])
items.value.push(4) // 触发视图更新
3.3 跨组件传递场景
// 父组件
const count = ref(0)
provide('count', count)
// 子组件
const count = inject('count')
count.value++ // 触发父组件视图更新

四、常见问题与解决办法
4.1 问题:响应性失效
- 原因:直接替换对象(如
obj = {name: '李四'})。 - 解决:使用
Object.assign合并更新(如Object.assign(obj, {name: '李四'}))。
4.2 问题:模板中.value缺失
- 原因:模板中未自动解包。
- 解决:确保在模板中直接使用变量(如
{{ count }})。
4.3 问题:深度监听失效
- 原因:
watch未开启深度监听。 - 解决:使用
watch的deep选项(如watch(state, () => {}, { deep: true }))。

五、源码视角与推荐
5.1 源码解析
- ref:通过
createRef创建RefImpl实例,内部存储_value属性。 - reactive:通过
Proxy代理对象属性,实现深度响应式追踪。
5.2 官方推荐
Vue3官方文档更推荐使用ref,因其灵活性和适用性更广。但在处理复杂嵌套对象时,reactive更简洁。
六、总结
ref和reactive是Vue3响应式系统的核心API,通过合理选择和组合,可实现高效的数据追踪和视图更新。理解其底层原理和适用场景,是掌握Vue3开发的关键。
743

被折叠的 条评论
为什么被折叠?



