响应性丢失:如何使用深层computed setter实现对象v-model绑定?
根本原因
你当前的写法里,v-model="computedValue.id" 是直接修改 computedValue 返回的对象的内部id属性,没有对computedValue本身做整体赋值操作,因此computed的setter永远不会被触发。
解决方案
方案1:单独处理每个属性的双向绑定
适合组件内修改的属性较少的场景,直接手动处理属性的更新逻辑,符合Vue单向数据流规范:
<template> <div class="h-2/3 w-2/3 bg-green-500"> <!-- 手动绑定value + 输入事件,不直接修改props --> <input :value="modelValue.id" @input="updateId($event.target.value)" /> {{modelValue}} </div> </template> <script> export default { name: 'TestModal', props: { modelValue: { type: Object, }, }, emits: ["update:modelValue"], methods: { updateId(newId) { // 生成新对象返回给父组件,不修改原props引用 this.$emit('update:modelValue', { ...this.modelValue, id: newId }) } }, } </script>
方案2:深监听本地拷贝(多属性场景推荐)
如果需要修改的属性很多,逐个写事件逻辑太繁琐,可以做一份props的本地拷贝,深度监听拷贝对象的变化自动同步给父组件:
<template> <div class="h-2/3 w-2/3 bg-green-500"> <!-- 直接绑定本地拷贝的属性 --> <input v-model="localModel.id" /> <input v-model="localModel.name" /> {{localModel}} </div> </template> <script> export default { name: 'TestModal', props: { modelValue: { type: Object, }, }, emits: ["update:modelValue"], data: () => ({ localModel: {} }), watch: { // 监听父组件传值变化,同步更新本地拷贝 modelValue: { immediate: true, handler(newVal) { // 简单对象用扩展运算符拷贝,复杂嵌套对象可以用自定义深拷贝方法 this.localModel = {...newVal} } }, // 深度监听本地对象变化,自动同步给父组件 localModel: { deep: true, handler(newVal) { console.log("数据更新,触发emit") this.$emit('update:modelValue', {...newVal}) } } } } </script>
注意事项
- 不要直接修改props对象的属性,所有变更都通过
emit通知父组件更新源数据,符合单向数据流要求 - 如果是复杂嵌套对象,拷贝时要用深拷贝方法,避免拷贝后的对象和原props对象共享引用
内容的提问来源于stack exchange,提问作者SPQRInc
相关产品推荐
相关产品推荐

