子组件能响应父组件props更新的前提是数据响应式且传递正确;使用ref/reactive创建数据并用v-bind传递可实现自动更新,而普通对象、解构值等非响应式方式会导致更新失效。

父组件动态改变 props 值时,子组件会自动响应更新——前提是数据本身是响应式的,且传递方式正确。
响应式数据能触发视图更新
当父组件使用 ref 或 reactive 创建的数据,并通过 :prop-name="xxx" 绑定传给子组件时,子组件中的 props 会随父组件数据变化而同步更新。
- 例如:
const count = ref(0),父组件传:count="count",子组件{{ count }}会实时响应 - 对象或数组也需保持响应式:用
reactive({ theme: 'dark' })而非普通对象字面量 - 直接替换整个引用(如
config = reactive({...}))也能触发更新,但修改内部属性更稳妥
非响应式数据不会自动更新
若父组件传的是普通对象、数组字面量或解构后的值,子组件将无法感知后续变化。
- 错误示例:
:user="{ name: 'Tom' }"→ 子组件接收的是只读副本,改props.user.name会报错 - 错误示例:
const { name } = props→ 解构后失去响应性,父组件改user.name不影响name变量 - 正确做法:在子组件中始终通过
props.xxx访问,或用toRefs(props)保持响应链接
异步更新与生命周期时机
Vue 的更新是异步批量的,所以父组件赋值后不能立刻在子组件中读取到新值(比如在 watch 或 onUpdated 之外的地方立即取值)。
- 想确保拿到最新值,可用
nextTick()包裹读取逻辑 - 首次渲染前 props 已就绪,但
setup()中同步访问 props 是安全的 - 避免在
mounted钩子中依赖 props 刚更新的值,除非配合watch或nextTick
避免常见陷阱
有些写法看似动态,实则切断了响应链。
- 不要在子组件中做
let local = props.count→ 后续父组件更新不影响local - 不要用
ref(props.count)初始化 —— 它只取初始快照,不跟踪变化 - 需要本地可变副本时,应
watch(() => props.count, (newVal) => localCount.value = newVal) - 复杂对象建议用
toRef(props, 'config')或computed(() => props.config)保持联动










