不能直接解构 props,因其为响应式 Proxy,解构后丢失响应性;正确方式有三:① toRefs 全量转换,② toRef 按需提取,③配合 defineProps 使用 toRefs 保障类型与响应性。

在 Vue 3 的 setup 函数中,第一个参数 props 是一个响应式对象(Proxy),**不能直接用 ES6 解构**,否则会丢失响应性 —— 这是新手最常踩的坑之一。
为什么不能直接解构 props?
props 是 Vue 创建的响应式代理对象,其响应性依赖于对原始对象属性的访问追踪。一旦解构(如 const { title, count } = props),得到的是普通变量,脱离了响应式系统,后续 props 更新时,这些变量不会自动更新。
正确解构响应式 props 的 3 种方式
✅ 推荐:使用 toRefs(适用于所有 props)
将整个 props 转为一组响应式引用,解构后仍保留响应性:
import { toRefs } from 'vue'
export default {
props: ['title', 'count'],
setup(props) {
const { title, count } = toRefs(props) // ✅ 响应式解构
// title.value 和 count.value 可读可写,且响应更新
return { title, count }
}
}
✅ 按需提取:用 toRef(只取个别字段)
当只需响应式地使用某几个 prop 时更轻量:
import { toRef } from 'vue'
setup(props) {
const title = toRef(props, 'title') // ✅ 单个响应式 ref
const count = toRef(props, 'count')
return { title, count }
}
⚠️ 注意:避免在 setup 中直接解构 + 使用 ref 包裹(常见误区)
以下写法看似“修复”,实则无效:
// ❌ 错误:ref 包裹的是初始值,不随 props 更新
const { title } = props
const titleRef = ref(title) // titleRef.value 不会响应 props.title 的变化
配合 defineProps 的现代写法(推荐组合)
使用 defineProps 宏时,toRefs 依然适用,且类型推导更友好:
<script setup lang="ts">
import { toRefs } from 'vue'
interface Props {
title: string
count: number
}
const props = defineProps<Props>()
const { title, count } = toRefs(props) // ✅ 类型安全 + 响应式
// 模板中可直接用 {{ title }},无需 .value(模板中自动解包)
</script>
需要修改 props?请先确认是否合理
Vue 默认禁止子组件直接修改 props(单向数据流)。如果确实需要“双向绑定”:
- 父组件用
v-model或:xxx.sync(Vue 2)/v-model:xxx(Vue 3)传入 - 子组件触发
update:xxx事件,或使用defineModel(Vue 3.4+) - 不要试图通过
toRef后赋值来“修改 props”,这违反设计原则且可能报错

















