Vue组合式API如何正确解构props不会丢失响应性
作者:人猫神话 大家的林语冰
解构 props
编译器宏 defineProps()
可以辅助读写提供给 <script setup>
中的组件的 props
:
上述示例中,props
是一个响应式对象,包含了提供给组件的 props
。如果组件 props
变化了,props
响应式对象也会随之变化。
读写 props
对象时,我们要做的第一件事可能是,解构 props
对象,然后读写各个属性。但当我学习 Vue 组合式 API 时,令我大吃一惊的是,解构的 props
丢失了响应性!
让我们来看一个例子。下述组件 <EvenOdd :count="5">
接受 count
属性作为数字,并显示一条消息,无论 count
是偶数还是奇数。
在解构 props
对象 const { count } = defineProps()
之后,访问该 count
属性:
单击几次增加按钮。您会注意到,尽管 count
属性不断累加,但 "The number is even"
消息始终保持不变。
当解构 props
对象 const { count } = defineProps()
时,响应性就会丢失。
响应性之所以会丢失,是因为在解构时 count
变异为具有原始值的变量(一个平平无奇的数字罢了)。但 Vue 的响应性不能直接作用于原始值:Vue 必须诉诸 ref
或响应式对象。
粉丝请注意,在 Vue 中将原始值直接赋值给变量时要小心:此乃丢失响应性的前提。
解决方案 1:使用“props”对象
第一个显而易见的解决方案是,不要解构 props
对象,并使用属性读写器直接读写 props
: props.count
。
上述示例中,读写 computed()
内的 props.count
可以在 props.count
变更时保留响应性。props
对象是响应式的,对其进行任何变更都会被正确追踪。
这种方案的短板是,我们必须始终使用属性读写器(比如 props.count
)来读写 <script setup
中的 prop
。
解决方案 2:使用 toRefs() 辅助函数
如果您阅读至此,我敢打赌您是解构赋值的忠实粉丝,并且没有它就活不下去。
问题不大,那么您可以有意识地将 props
对象的每个属性转换为 ref
,来保留解构 props
的响应性。Vue 提供了一个特殊的辅助函数 toRefs(reactiveObject)
来精准完成此操作。
其工作机制如下:
toRefs(props)
返回一个对象,其中每个属性都是对相应 prop
的 ref
。
现在解构 const { count } = toRefs(props)
是安全的,因为 count
是基于 count
属性的 ref
。现在,每次 count
属性变更时,count
的 ref
都会响应属性更改。
将 count
作为 ref
,在 computed()
内,我们必须使用 count.value
读写 prop
的值(因为 count.value
是我们读写 ref
的值的方式)。
我发现此方案可以方便地将 prop ref
作为参数传递给组合式函数:比如 useMyComposable(count)
,并且不会丢失响应性。
否则,我会坚持之前的方案,直接使用 props
对象读写 prop
。
总结
粉丝请注意,通过应用解构 const { propA, propB } = defineProps()
,我们会丢失 props
的响应性。
解决响应性丢失的方案主要有两种:
不解构
props
,而是诉诸属性读写器直接读写props
:比如props.xxx/props.cat
。有意识地使用
props
作为refs
的对象:const { propA, propB } = toRefs(props)
。这保留了解构后的响应性。然后我们可以将属性作为独立ref
读写,比如propsA.value/propB.value
等。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考,英文原味版请传送 How to Destructure Props in Vue (Composition API)
以上就是Vue组合式API如何正确解构props不会丢失响应性的详细内容,更多关于Vue组合式API解构props的资料请关注脚本之家其它相关文章!