在最新的版本3.5x中,对props的能力也进行了加强。下面,我们具体看下有哪些变化,给我们带来的新的体验!
体验一
- 3.5之前解构props的效果
// 子组件
<template><div><h1>响应式props</h1><p>{{ count }}</p></div>
</template><script setup>
import { watch, watchEffect } from "vue";
const { count } = defineProps(["count"]);watchEffect(() => {console.log("count", count);
});
watch(() => count,newVal => {console.log("count", newVal);}
);
</script>
// 父组件
<template><div><ChildProps :count="count" /><button @click="count++">Click me</button></div>
</template><script setup>
import ChildProps from "@/components/ChildProps";
import { ref } from "vue";
const count = ref(0);
</script>
- 代码解析
- 子组件解构父组件传来的count数据,在子组件中是无法
watch
到count
的更新的,如上图 - 同样的代码,只需更换vue版本到3.5,监听就会生效了,如下图
- 解析出来的
count
,在进行watch
时,不能直接传count
,要用对应的get
- 反例:这并不会按预期工作,因为它等价于
watch(props.foo, ...)
——我们给watch
传递的是一个值而不是响应式数据源。实际上,Vue 的编译器会捕捉这种情况并发出警告。
watch(count, /* ... */)
- 子组件解构父组件传来的count数据,在子组件中是无法
体验二
将我们结构出来的props属性,传给自定义的hooks,保持数据的响应性,那怎么做?
- 实现效果
- 代码实现
// 自定义hooks
import { toValue, ref, watchEffect } from "vue";
export function useCountAdd(num) {let computedCount = ref(0);watchEffect(() => {computedCount.value = toValue(num) + 1;});return computedCount;
}
- 父组件
<template><div><h1>响应式props</h1><p>{{ count }}</p><p>{{ newCount }}</p></div>
</template><script setup>
import { useCountAdd } from "@/hooks/useCount";const { count } = defineProps(["count"]);// (1)
const newCount = useCountAdd(count);
</script>
(1):如果直接传递解构出来的count
,我们的页面是不能及时响应更新的。
正例:
const newCount = useCountAdd(() => count);