Vue3全家桶升级指南二ref、toRef、toRefs的区别

Vue3响应式数据管理:ref vs toRef与toRefs的区别
本文介绍了Vue3中ref和toRef/toRefs的使用及其区别,包括数据拷贝与引用、视图更新与原始数据同步。重点讲解了如何高效地处理基础类型和引用类型数据,以及toRefs在保持数据同步但隐藏细节的应用场景。

ref是对原始数据的拷贝,当修改ref数据时,模板中的视图会发生改变,但是原始数据并不会改变。
toRef是对原始数据的引用,修改toRef数据时,原始数据也会发生改变,但是视图并不会更新。

在vue3中定义一个基础类型的响应式数据一般使用ref,定义一个引用类型的响应式数据一般使用reactive。

import {ref,reactive} from "vue"
export default {
    setup(){
    let num=ref(0)
    let obj=reactive({name:'张三',age:18})
    return {num,obj}    
}
}

这样在模板中使用的时候,就可以直接通过{{num}},{{obj.name}},{{obj.age}}获取数据了。

基础类型的数据没有问题,但是引用类型的值在模板中这样写就比较累赘了,我们也可以直接解构出来,在模板中就可以直接使用{{name}}和{{age}}了。

import {ref,reactive} from "vue"
export default {
    setup(){
        let num=ref(0)
        let obj=reactive({name:'张三',age:18})
        let {name,age}=obj
        return {num,name,age}
    }
}

toRef是将对象中的某个值转化为响应式数据 toRef(obj,key)

import {toRef} from "vue"
export default {
    setup() {
        let obj = { name: '张三', age: 18 };
        let newObj = toRef(obj, 'name');
        setTimeout(() => {
            newObj.value = '李四';
            console.log(obj, newObj); //obj中的name和newObj都变成李四了,但是视图显示还是张三,不会变化
        }, 2000);
        return { obj, newObj };
    },
};
</script>

toRef是对原始数据的引用,修改toRef数据时,原始数据也会发生改变,但是视图并不会更新。

toRefs是将整个对象转化成响应式数据 toRefs(obj)

import {toRefs} from "vue"
export default {
    let obj = { name: '张三', age: 18 };
        let newObj = toRefs(obj);
        setTimeout(() => {
            newObj.name.value = '李四';
            console.log(obj, newObj);
        }, 2000);
        return { obj, newObj };
}

需要注意的是,按照上面这种写法,在模板中使用的时候,需要按照这种方式 {{newObj.name.value}}(不太理解),如果想直接使用{{name}},那么在setup中return的时候需要解构下

import {toRefs} from "vue"
export default {
    let obj = { name: '张三', age: 18 };
        let newObj = toRefs(obj);
        setTimeout(() => {
            newObj.name.value = '李四';
            console.log(obj, newObj);
        }, 2000);
        return { obj, ...newObj };
}

这样在模板中就可以直接通过{{name}}来获取了。

小结一下

1、ref是对元数据的拷贝,修改响应式数据时不会影响之前的数据,视图会更新

2、toRef和toRefs是对元数据的引用,修改响应式数据时,元数据也会改变,但是视图不会更新,toRef修改的是对象的某个属性,toRefs修改的是整个对象

3、toRefs的使用场景:如果想让响应式数据和原来的数据关联起来同步更新,并且不更新视图,那么就可以使用toRefs

Vue 3 的响应式系统中,`ref`、`reactive`、`toRef` 和 `toRefs` 是处理响应式数据的核心工具。它们各自适用于不同的数据结构和使用场景,正确理解其区别有助于构建高效、可维护的 Vue 应用程序。 ### `ref` `ref` 用于创建一个响应式的引用对象,通常用于基本类型数据(如数字、字符串、布尔值等)。它通过 `.value` 属性来访问或修改内部值。在模板中使用时,Vue 会自动解包 `.value`,无需手动调用。适用于独立的基本类型数据或需要显式控制响应性的场景。 ```javascript import { ref } from &#39;vue&#39;; const count = ref(0); count.value++; // 修改值 ``` 在组合式 API 中,`ref` 常用于组件间通信,例如通过 `v-model` 或 `props` 传递响应式数据[^1]。 ### `reactive` `reactive` 用于创建一个响应式的对象,适用于复杂的数据结构(如对象、数组)。它返回一个响应式代理,所有属性的修改都会触发视图更新。`reactive` 不适用于基本类型数据,否则会抛出错误。 ```javascript import { reactive } from &#39;vue&#39;; const state = reactive({ count: 0, name: &#39;Vue&#39; }); state.count++; // 修改对象属性 ``` `reactive` 适合用于管理一组相关的状态,尤其是对象结构较深的场景。但需要注意,解构响应式对象会导致失去响应性,此时需要结合 `toRefs` 使用[^3]。 ### `toRef` `toRef` 用于从响应式对象中提取一个 `ref`,并保持与原始对象属性的响应性同步。适用于仅需提取某个属性并保持响应性的场景,尤其在解构或传递单个属性时非常有用。 ```javascript import { reactive, toRef } from &#39;vue&#39;; const state = reactive({ count: 0 }); const countRef = toRef(state, &#39;count&#39;); countRef.value++; // 修改会同步到 state.count ``` `toRef` 的优势在于它不会创建新的响应式副本,而是直接引用原始对象的属性,因此在性能上更优[^4]。 ### `toRefs` `toRefs` 用于将响应式对象的所有属性转换为 `ref`,并保持响应性。返回的是一个普通对象,其每个属性都是 `ref`,适用于解构响应式对象并保持所有属性的响应性。 ```javascript import { reactive, toRefs } from &#39;vue&#39;; const state = reactive({ count: 0, name: &#39;Vue&#39; }); const { count, name } = toRefs(state); count.value++; // 修改会同步到 state.count ``` `toRefs` 特别适用于在 `setup()` 函数中将响应式对象作为解构对象返回,确保模板中使用时仍保持响应性[^2]。 ### 使用场景对比 | 工具 | 适用类型 | 是否解包 | 使用场景 | |-----------|----------------|----------|--------------------------------------| | `ref` | 基本类型 | 是 | 独立值、组件通信、显式控制响应性 | | `reactive`| 对象、数组 | 否 | 多属性对象、深层结构、整体响应性 | | `toRef` | 对象单个属性 | 是 | 提取单个属性并保持响应性 | | `toRefs` | 对象所有属性 | 是 | 解构对象、保持所有属性响应性 | ### 总结 - 使用 `ref` 处理基本类型数据或需要显式 `.value` 控制的场景。 - 使用 `reactive` 管理复杂对象或数组的响应性。 - 使用 `toRef` 提取对象中的单个属性并保持响应性。 - 使用 `toRefs` 解构响应式对象的所有属性并保持响应性。 在实际开发中,应根据数据类型和结构选择合适的响应式工具,以确保性能和代码的可维护性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值