[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

图1 - 解构赋值失去响应式

bar.val 会更新?

这与深层响应式有关,reactive 会递归地创建嵌套对象的响应式。所以,解构第一层对象属性会丢失响应式,而第二层依旧还是响应式对象。

toRef 提取属性

toReftoRefs基于响应式对象上的一个或多个属性,引用原本的响应式对象。

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>

通过 toRefsfoobar 不会丢失响应式,它们和 obj 是双向的。所以,操作 obj 也会反馈给 foo 和 bar,反之亦然。

图2 - 延续响应式能力

toRef 和 Props

file:[Test.vue]
<script setup>
const props = defineProps(/* ... */)

// 将 `props.foo` 转换为 ref,然后传入一个组合式函数
useRefHistory(toRef(props, "foo"));
</script>

foo 的数据更改了,也会让 useRefHistory 传递的参数更新。

posted @ 2023-03-19 00:13  Himmelbleu  阅读(762)  评论(0编辑  收藏  举报