VUE3-toRef和toRefs
toRef
也可以基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。
toRefs
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
代码
<template>
<h2>{{data}}</h2>
<h2>计数器:{{counter1}}</h2>
<button @click="counter1++">计数器加1</button>
<hr>
<h2>计数器2:{{counter2}}</h2>
<button @click="counter2++">计数器加1</button>
<hr>
<h2>计数器3:{{a.b.counter3}}</h2>
<button @click="a.b.counter3++">计数器加1</button>
</template>
<script>
import {
ref,
toRef,
reactive,
toRefs
} from 'vue'
export default {
setup() {
// data
let data = reactive({
counter1: 1,
counter2: 100,
a: {
b: {
counter3: 1000
}
}
})
// 这样写肯定不行,因为这种方式第一次打开页面的时候,能够看到数据,但是不是响应式的。因为这个数据和data无关了
// return {
// counter1: data.counter1,
// counter2: data.counter2,
// counter3: data.a.b.counter3
// }
// 下面这种方式可以完成响应式
// 问题是什么?计数器加1的时候,data对象中的数据不会变
// return {
// counter1: ref(data.counter1),
// counter2: ref(data.counter2),
// counter3: ref(data.a.b.counter3)
// }
// 因为上面这样写与下面的写法没有区别
// return {
// counter1: ref(1),
// counter2: ref(100),
// counter3: ref(1000)
// }
// 由于上面的原因,则引入了下面toRef
// toRef语法格式:toRef(对象,'该对象中的属性名')
// toRef函数执行之后会生成一个全新的对象:objectRefImpl(引用对象)
// 这个引用对象会与指定的数据形成响应式,相当于在两个数据直接搭建了桥梁
// 只要有引用对象,就有value属性,并且value属性是响应式的。(value有对应的set和get。)
console.log(toRef(data, 'counter1'));
// return {
// data,
// counter1: toRef(data, 'counter1'),
// counter2: toRef(data, 'counter2'),
// counter3: toRef(data.a.b, 'counter3')
// }
// 但是上面这个写法太繁琐了,所有就有了使用toRefs来进行简写
// toRefs
// toRefs函数用法:toRefs(data)
console.log(toRefs(data)) // 这个生成的是一个对象
return {
data,
...toRefs(data)
}
// 相当于上面简写相当于下面
// return {
// data,
// counter1: toRef(data, 'counter1'),
// counter2: toRef(data, 'counter2'),
// a:{
// b:{
// counter3: toRef(data.a.b, 'counter3')
// }
// }
// }
}
}
</script>
涉及内容
vue3、toRef、toRefs