Vue3中父组件将一个ref定义的对象类型传递给子组件的解包机制
在Vue3中,当父组件将一个ref
定义的对象类型传递给子组件时,子组件接收到的不是原始的Ref
类型,而是该ref
的.value
值,即被解包后的响应式对象。具体行为如下:
关键点解析:
-
自动解包机制:
Vue3在模板中会自动解包ref
,因此在父组件中传递ref
给子组件的prop
时,实际传递的是ref.value
(即内部值)。子组件接收到的prop
会是一个普通的对象(若ref
的值是对象),而非Ref
类型。 -
响应式保持:
如果父组件的ref
值是对象,Vue会通过reactive()
自动将其转换为响应式代理。因此,子组件接收到的对象仍然是响应式的。直接修改该对象的属性会触发响应式更新,父子组件的状态会同步。 -
验证示例:
-
父组件传递
ref
对象:vue
<template> <Child :myProp="myRef" /> </template> <script setup> import { ref } from 'vue'; const myRef = ref({ name: 'Parent' }); </script>
-
子组件接收
prop
:vue
<template> <!-- 直接使用属性,无需.value --> <div>{{ myProp.name }}</div> </template> <script setup> defineProps(['myProp']); </script>
-
子组件的
myProp
是解包后的对象,直接访问myProp.name
即可,且修改myProp.name
会触发父组件更新。
-
注意事项:
-
直接修改对象属性:
若子组件修改接收到的对象属性(如myProp.name = 'new'
),会同步修改父组件的状态,因为两者引用同一个响应式对象。 -
替换整个对象:
如果子组件需要替换整个对象,应通过事件通知父组件修改ref.value
。直接赋值(如myProp = {}
)不会影响父组件,因为prop
是只读的。
总结:
父组件的ref
对象传递给子组件后,子组件接收到的是解包后的响应式对象,而非Ref
类型。因此,在子组件中无需使用.value
访问,直接操作属性即可保持响应式。