vue 中 props 直接解构的话会数据丢失响应式
项目中,vue父子组件传参时,如果直接解构的话会丢失响应式
<script setup>const props = defineProps({count: Number});let { count } = props;count++;console.log(props.count) // 结果0,count并不会发生变化<script>
想解构成响应式数据需要使用 toRefs 或 toRef
- 当使用 reactive 创建一个响应式对象时,对象的属性是响应式的,但直接解构(如 const { name } = state)会使 name 变成普通值,失去响应性。
- toRefs 和 toRef 通过创建 ref 对象来包装属性,确保在解构后属性仍能响应式更新。
例子1
<script setup>import {toRef, toRefs} from \'vue\';const props = defineProps({msg: String,count: Number});// _msg是响应式的,会随着props.msg改变const _msg = toRef(props,\'msg\');// msg,count也是响应式的,会随着props改变const { msg, count } = toRefs(props);<script>
例子2
<script setup>import { reactive, toRefs } from \'vue\';// 创建一个响应式对象const state = reactive({ name: \'Alice\', age: 30});// 使用 toRefs 解构,保持响应性const { name, age } = toRefs(state);// 现在 name 和 age 都是 ref 对象,可以通过 .value 访问console.log(name.value); // 输出: \'Alice\'// 修改原对象,name 和 age 会响应式更新state.name = \'Bob\';console.log(name.value); // 输出: \'Bob\'// 使用 toRef 解构单个属性const nameRef = toRef(state, \'name\');// 现在 nameRef 是一个 ref 对象console.log(nameRef.value); // 输出: \'Alice\'<script>
注意点
- 响应性保持:解构后的 ref 对象会同步更新原对象的值,反之亦然。
- 性能:toRefs 和 toRef 是轻量级操作,不会导致性能问题。
- 错误场景:避免直接解构响应式对象(如 const { name } = state),这会导致 name 失去响应性。
- 替代方案:在 Vue 3 中,也可以使用 ref 创建独立响应式变量,但 toRefs 和 toRef 更适合处理对象属性。