首先简单看看下面这个小demo
<div>
<h3>个人信息</h3>
<p>姓名:{{person.name}}</p>
<p>年龄:{{person.age}}</p>
<p>爱好:水果--{{person.love.fruits}}, 蔬菜--{{person.love.vegetables}}</p>
</div>
import {reactive} from 'vue'
export default {
setup() {
let person = reactive({
name: 'fufu',
age: 20,
love: {
fruits: 'watermelon',
vegetables: 'potato'
}
})
return {person}
}
}
当我们简单抛出一个对象时,在模板里面引入时,就需要层层写出,有人就可能想到能不能导出单个属性值。
<div>
<h3>个人信息</h3>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
<p>爱好:水果--{{fruits}}, 蔬菜--{{vegetables}}</p>
</div>
import {reactive} from 'vue'
export default {
setup() {
let person = reactive({
name: 'fufu',
age: 20,
love: {
fruits: 'watermelon',
vegetables: 'potato'
}
})
return {
name: person.name,
age: person.age,
fruits: person.love.fruits,
vegetables: person.love.vegetables
}
}
}
可以发现显示出来的效果跟之前的demo一样,但是当改变模板里面的数据时,却发现模板数据并不改变。这是为什么呢?稍微有些js基础的人应该都知道,当我们返回一个
return {
name: person.name,
age: person.age,
fruits: person.love.fruits,
vegetables: person.love.vegetables
}
对象时,其实这已经是一个新的对象了,相当于进行了解构赋值,返回的对象已经不再是一个响应式对象了,而是一个新的普通对象,所以当数据改变不会在模板上体现。
这个时候就需要一个新的api来帮助我们了—— toRef
toRef
toRef使用也需要自行进行引入,为一个函数,里面有两个参数。参数一为一个响应对象,参数二为参数一这个对象中的某个属性。并将这个属性扎转换为响应式数据。
return {
name: toRef(person, 'name'),
age: toRef(person, 'age'),
fruits: toRef(person.love, 'fruits'),
vegetables: toRef(person.love, 'vegetables')
}
这样我们就可以在模板上直接使用返回的属性,并且该属性也是响应式的。
但是我们也可以很清晰的看到toRef的缺陷,如果要抛出多个属性,就得使用多次toRef进行转换,有什么解决办法吗?toRefs就此出现。
toRefs
toRef使用也需要自行进行引入,为一个函数,里面有一个参数。参数一为一个响应对象,它会自动将里面的所有属性都转换为响应式数据,并保存引用关系。
return {
...toRefs(person)
}
有人会问为什么返回的对象里面需要进行解构呢?因为toRefs(person)返回的本就是一个对象,不进行解构赋值不就变成{{}}这种结构了,会报错。