Vue3中如何响应式解构 props

Props | Vue.js (vuejs.org)

Vue3 中为了保持响应性,始终需要以 props.x 的方式访问这些 prop。

所以不能够解构 defineProps 的返回值,因为得到的变量将不是响应式的、也不会更新。举例:

<template>
  <!-- count 始终为 0 -->
  <div>{{ count }}</div>
  <!-- info 始终为 { age: 18 } -->
  <div>{{ info }}</div>
</template>

<script setup lang="ts">

const props = defineProps<{
	count: number;
	info: object;
}>();

const { count, info } = props;
</script>

1、父组件

<template>
  <Children :count="count" :info="info"  />
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import Children from "./Comp.vue";

const count = ref(0);
const info = ref({
	age: 18,
});
setTimeout(() => {
	count.value++;
	//info.value.age = 98
	info.value = { age: 99 };
}, 1000);
</script>

2、子组件,方式一:直接解构,注意:vue@3.5 才完美支持此方式

<template>
  <div>{{ localcount }}</div>
  <div>{{ info }}</div>
  <button @click="onClick">点击</button>
</template>

<script setup lang="ts">
import { watchEffect, watch } from "vue";

const { count: localcount = 0, info = { age: 17 } } = defineProps<{
  count: number;
  info: object;
}>();

const onClick = () => {
  console.log("onClick:count:",localcount);
};

watchEffect(() => {
  console.log("watchEffect:count:", localcount);
});

watch(() => localcount,
  () => { console.log("watch:count:", localcount); },
  { immediate: true })
</script>

3、子组件,方式二:toRef 和 toRefs

toRef,基于响应式对象上的一个属性,创建一个对应的 ref,这个 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值。

toRefs,将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。

<template>
  <div>{{ count }}</div>
  <div>{{ info }}</div>
  <button @click="onClick">点击</button>
</template>

<script setup lang="ts">
import { toRef, toRefs, watchEffect, watch } from "vue";

const props = defineProps<{
  count: number;
  info: object;
}>();

// 2种写法都行。
// const count = toRef(props, "count");
// const info  = toRef(props, "info");
const { count, info } = toRefs(props);

const onClick = () => {
  console.log("onClick:count:", count.value);
};

watchEffect(() => {
  console.log("watchEffect:count:", count.value);
});

watch(() => count.value,
  () => { console.log("watch:count:", count.value); },
  { immediate: true })

//或者

watch(count,
  () => { console.log("watch:count:", count.value); },
  { immediate: true })
</script>

结果:

1727330810495

posted on 2024-09-26 09:29  springsnow  阅读(235)  评论(0编辑  收藏  举报

导航