历史小剧场
知道可能面对的困难和痛苦,在死亡的恐惧中不断挣扎,却仍然能战胜自己,选择这条道路,这才是真正的勇气。----《明朝那些事儿》
前言
toRef 和 toRefs 是Vue3中的响应式转换工具函数
- toRef: 不影响源对象的情况下,对属性进行单独的访问和修改。toRef函数正是为了解耦属性的关联,将属性转换为一个独立的ref对象。并且:两者之间同步更新。
- toRefs: 在父组件向子组件传递属性时,需要将这些属性声明为响应式对象。但是,如果直接将整个响应式对象传递给子组件,子组件无法通过解耦或者直接访问每个属性。又或者是在单页面上数据双向绑定时在View层不想要写这个响应式对象点的形式而是直接访问属性。这时,toRefs函数就可以将整个响应式对象转换为一个普通对象,每个属性都是独立的ref对象,可以轻松解耦和访问这些属性。
案例
<!-- TestToRef.vue -->
<template><div><h1>info.name {{ name }}</h1><h1>nameRef.value {{ nameRef }}</h1><button @click="changInfoName">改变info.name</button><button @click="changNameRef">改变nameRef.value</button></div>
</template><script lang="ts">
import { reactive, toRef, toRefs } from 'vue';export default {setup() {const info = reactive({name: '章三',age: 25})const nameRef = toRef(info, 'name')console.log(nameRef.value)const infoRefs = toRefs(info)console.log(infoRefs)console.log({...infoRefs})const changInfoName = () => {info.name = '李四'}const changNameRef = () => {nameRef.value = '王五'}return {...infoRefs,nameRef,changInfoName,changNameRef}}
}
</script><style lang="scss" scoped></style>
在上面这个案例中:
- 当我们点击第一个按钮时,改变了源响应式对象里面的name属性,然后单独解耦出来的nameRef对象里的值同步变了。而当我们点击第二个按钮时,改变了单独解耦出来的nameRef对象里的值,然后源响应式对象里面的name属性也变了。这是toRef()函数在起作用
- 注意看代码里View层的代码,我们在插槽里直接写了源响应式对象里的两个属性值,直接解耦出来了。这是toRefs()函数在起作用
比较
相同点
- toRef和toRefs都用于将响应式对象的属性转换为ref对象;
- 转化后的属性仍然保持响应式,对属性的修改会反映到源响应式对象上;
- 在script中访问和修改其值都需要通过.value进行
不同点
- toRef修改的是对象的某个属性,生成一个单独的ref对象;
- toRefs修改的是整个对象,生成多个独立的ref对象集合;
- toRefs适用于在组件属性解耦或传递时使用;而toRef更适合提取单个属性进行操作。