0
点赞
收藏
分享

微信扫一扫

Vue3 toRef、toRefs

toRef

作用:创建一个 ​​ref​​​ 对象,其 value 值指向另一个对象中的某个属性。
语法:​​​const nane = toRef(person, ' name ')​​​ 应用:要将响应式对象中的某个属性单独提供给外部使用时
扩展:​​toRefs​​ 与 ​​toRef​​ 功能一致,但可以批量创建多个 ref 对象
语法:​​toRefs(person)​

在 ​​Vue3的响应式​​ 中,我们写了一段 js 来模拟 vue3 的响应式

<script>
//源数据
let person = {
name:"张三",
age:18
}
const p = new Proxy(person,{
//有人读取p的某个属性时调用
get(target, p, receiver) {
console.log(`有人读取了p身上的${p}属性`);
//return target[p]
return Reflect.get(target,p)
},
//有人修改、增加p的某个属性时调用
set(target, p, value, receiver) {
console.log(`有人修改了p身上的${p},我要去更新界面了`);
//target[p] = value
Reflect.set(target,p,value)
},
//有人删除p的某个属性时调用
deleteProperty(target, p) {
console.log(`有人删除了p身上的${p},我要去更新界面了`);
//return delete target[p]
return Reflect.deleteProperty(target,p)
}
})
</script>

Vue3 toRef、toRefs_响应式
当修改 p 的属性时,会检测到然后打印相应信息,现在在刚才这段 js 最后增加一句以下代码,然后我们尝试修改 name 属性

let name = p.name

先输出 person 、 p 、name 看下结构,然后修改 name,发现只是修改了 name,p 中的值并未受到影响
Vue3 toRef、toRefs_字段_02
然后我们来看下面一段代码,也是我们之前写过的例子,一个人的信息,然后点击按钮进行修改
Vue3 toRef、toRefs_数据_03

<template>
<h2>{{ person }}</h2>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<h2>薪资:{{ salary }}K</h2>
<button @click="name+='~'">修改姓名</button>
<button @click="age++">修改年龄</button>
<button @click="salary++">涨薪</button>

</template>

<script>
import {reactive, toRef} from 'vue'

export default {
name: 'Demo',
setup() {
let person = reactive({
name: "张三",
age: 18,
job: {
j1: {
salary: 20
}
}
})

const name1 = person.name;
console.log("name1", name1);

const name2 = toRef(person.name);
console.log("name2", name2);

return {
person,
name: toRef(person, "name"),
age: toRef(person, "age"),
salary: toRef(person.job.j1, "salary"),
}
}
}
</script>

之前我们 return 中只返回 person,然后取值时使用 person.name、person.age等,如果我们想返回它的某些字段,就需要使用 ​​toRef​​​,例如返回 name 属性 ​​name:toRef(person, "name")​​这样才能让数据依然是响应式的,在模板中可以直接使用 {{name}} 就可以取到值。如果在 return 中直接像以下代码这样写是不行的,因为返回的 name 不是响应式的

错误代码:
return {
name: person.name,
age: person.age,
salary: person.job.j1.salary,
}

上边代码中我们输出了 name1 和 name2,可以看到 name1 仅仅是一个字符串,而 name2 是一个 ObjectRefImpl 。这就解释了为什么直接返回 person.name 不是响应式的了
Vue3 toRef、toRefs_字段_04

toRefs

还是上边的代码,我们使用 toRefs,把 person 的第一层拆出来形成了一个对象,我们打印看看

const x = toRefs(person);
console.log(x);

Vue3 toRef、toRefs_vue_05
所以刚才的代码可以改为:

<template>
<h2>{{ person }}</h2>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<h2>薪资:{{ job.j1.salary }}K</h2>
<button @click="name+='~'">修改姓名</button>
<button @click="age++">修改年龄</button>
<button @click="job.j1.salary++">涨薪</button>

</template>

<script>
import {reactive,toRefs} from 'vue'

export default {
name: 'Demo',
setup() {
let person = reactive({
name: "张三",
age: 18,
job: {
j1: {
salary: 20
}
}
})

const x = toRefs(person);
console.log(x);

return {
person,
...toRefs(person)
}
}
}
</script>


举报

相关推荐

0 条评论