深度监听 ref 和 reactive 的区别详解

发布于:2025-04-18 ⋅ 阅读:(23) ⋅ 点赞:(0)


以下从响应式原理、监听方式和实际表现三个维度,分析二者的核心区别:

一、ref 的深度监听(示例代码)

<template>
    <div class="person">
        <p>嵌套值:{{ refObj.nested.value }}</p>
        <button @click="refObj.nested.value = '新的值'">修改值</button>
    </div>

</template>

<script lang="ts" setup>
import { ref, watch } from 'vue';
const refObj = ref({
    nested: {
        value: "初始值"
    }
});
watch(refObj, (newVal) => {
    console.log("ref 嵌套变化:", newVal.nested.value);
}, { deep: true }); // 必须显式设置 deep: true

watch(refObj.value, (newVal) => {
    console.log("ref 嵌套变化:", newVal.nested.value);
}); // 若改为监听refObj.value(即 reactive 对象),则无需 deep

</script>

关键点:

1. ref 的存储方式:

ref 会将对象包裹在 .value 属性中,底层自动用 reactive 转换嵌套对象。(即 refObj.value 是 reactive 代理对象)

2. 监听 ref 的特性
  • 直接监听 refObj(而非 .value)时,需要显式设置 deep: true 才能捕获嵌套属性变化。若不设置 deep,仅当整个 .value 被替换时才会触发监听。
  • 等价替代方案
    若改为监听 refObj.value(即 reactive 对象),则无需 deep:

二、reactive 的深度监听(示例代码)

const reactiveObj = reactive({ 
	nested: { 
		value: "初始值" 
	} 
});

watch(() => reactiveObj, (newVal) => {
    console.log("reactive 嵌套变化:", newVal.nested.value);
}, { deep: true }); // deep:true 在此处是冗余的

关键点:

1. reactive 的深度响应性

reactive 创建的代理对象默认支持深层级响应,修改任意嵌套属性都会触发更新。

2. 监听 reactive 的特性
  • 直接监听 reactiveObj 时,无需 deep 即可自动深度监听。
    示例代码中的 () => reactiveObj 是冗余写法,直接传递 reactiveObj 即可:
watch(reactiveObj, (newVal) => {
    console.log("reactiveObj 嵌套变化:", newVal.nested.value);
}); // 直接监听 reactiveObj 时,无需 deep 即可自动深度监听
  • 若监听一个返回 reactive 对象的函数(如 () => reactiveObj),需开启深度监听:{deep:true}
watch(()=>reactiveObj, (newVal) => {
    console.log("reactiveObj 嵌套变化:", newVal.nested.value);
},{deep:true}); // 监听一个返回reactive对象的函数,deep:true 开启深度监听
  • 若监听 reactiveObj.nested.value 时,需使用函数式写法()=>reactiveObj.nested.value,无需开启深度监听。
watch(()=>reactiveObj.nested.value,(newVal,oldVal)=>{
    console.log("reactiveObj 嵌套变化:", newVal,oldVal);
}); // 监听 reactiveObj.nested.value 时,需使用函数式写法,deep 选项无效

三、核心区别总结

特性 ref (对象类型) reactive
数据存储方式 包裹在 .value 中 直接代理对象
默认深度监听 否(需显式设置 deep)
推荐监听方式 监听 .value (无需 deep) 直接监听对象
适用场景 基本类型或需要替换整个对象 复杂对象,需深层级响应式

四、最佳实践建议

1. 优先使用 reactive

处理复杂对象时,reactive 的自动深度响应更简洁高效。

2. 明确 ref 的使用场景

当需要替换整个对象或处理基础类型时,选择 ref。

3. 简化 watch 配置

  • 监听 ref 的 .value 替代显式 deep
  • 直接传递 reactive 对象而非函数返回值

通过理解这些差异,可以更精准地选择响应式工具,并避免不必要的性能消耗。


网站公告

今日签到

点亮在社区的每一天
去签到