[Vue3] 响应式工具 toRef
解构赋值
file:[App.vue]
<script setup>
// 解构赋值
const { foo, bar } = { ...reactive({ foo: 1, bar: { val: 1 } }) };
</script>
<template>
<div>foo: {{ foo }}</div>
<button @click="foo++">Change foo</button>
<div>bar val: {{ bar.val }}</div>
<button @click="bar.val++">Click bar val</button>
</template>
如下图所示,点击 foo
多次视图都没有更新,但只有 bar.val
才会立即更新。视图了,所以会带着更新刚刚点击多次的 foo
。
bar.val 会更新?
这与深层响应式有关,reactive
会递归地创建嵌套对象的响应式。所以,解构第一层对象属性会丢失响应式,而第二层依旧还是响应式对象。
toRef 提取属性
toRef
或 toRefs
是基于响应式对象上的一个或多个属性,引用原本的响应式对象。
file:[App.vue]
<script setup>
import { reactive, toRefs } from "vue";
const obj = reactive({ foo: 1, bar: { val: 1 } });
const { foo, bar } = toRefs(obj);
function changeFoo() {
foo.value++;
}
function changeBar() {
bar.value.val++;
}
</script>
<template>
<div>foo: {{ foo }}</div>
<button @click="changeFoo">Change foo</button>
<div>bar: {{ bar.val }}</div>
<button @click="changeBar">Change bar</button>
</template>
通过 toRefs
,foo
和 bar
不会丢失响应式,它们和 obj
是双向的。所以,操作 obj 也会反馈给 foo 和 bar,反之亦然。
toRef 和 Props
file:[Test.vue]
<script setup>
const props = defineProps(/* ... */)
// 将 `props.foo` 转换为 ref,然后传入一个组合式函数
useRefHistory(toRef(props, "foo"));
</script>
当 foo
的数据更改了,也会让 useRefHistory
传递的参数更新。