toRefs作用:
toRefs函数的作用是将响应式对象中的所有属性转换为单独的响应式数据,对象成为普通对象,并且值是关联的。
做了两件事:
- 把一个响应式对象转换成普通对象
- 对该普通对象的每个属性都做一次ref操作,这样每个属性都是响应式的
注意:
- reactive 对象取出的所有属性值都是非响应式的,而利用 toRefs 可以将一个响应式 reactive 对象的所有原始属性转换为响应式的 ref 属性。
- reactive的响应式功能是赋值给对象,如果展开对象,会让数丢失响应的能力
- 使用toRefs可以保证对象展开的每个属性都是响应式的。
应用场景:
- 展开响应式对象时,想使用响应式对象中的多个或者所有属性做为响应式数据。
- 当函数返回响应式对象时,toRefs非常有用,这样消费组件就可以在不丢失响应式的情况下对返回的对象进行分解使用。
<template>
<div>品牌:{{brand}}</div>
<div>价格:{{price}}</div>
<button @click="owner='小华'">过户给小华</button>
</template>
<script lang='ts'>
import { reactive } from 'vue'
export default {
setup() {
const user = reactive<any>({
owner: '小明',
car: {
brand: '保时捷',
price: 1500000,
}
})
return {
...user // 展开运算符
}
}
}
</script>
注意:
上面返回的使用 使用...state, 使用了展开运算符展开state, 使得基本类型owner属性失去了响应式,而car是一个对象,所以没有影响 还是响应式的。所以上面代码,单击button时,不能改变页面显示效果。
解决办法:
<template>
<div>品牌:{{brand}}</div>
<div>价格:{{price}}</div>
<button @click="owner='小华'">过户给小华</button>
</template>
<script lang='ts'>
import { reactive, toRefs } from 'vue'
export default {
setup() {
const user = reactive<any>({
owner: '小明',
car: {
brand: '保时捷',
price: 1500000,
}
})
return {
...toRefs(user)
}
}
}
</script>
总结:把一个响应式对象转换成普通对象,该普通对象的每个属性都是一个ref, ref可以使基本类型变成响应式的,可以把复杂类型自动传为reactive,所以使得复杂类型也是响应式的