Vue3数据响应异常求助:子组件data属性莫名重置
Vue3 动态组件v-model响应异常问题修复
问题根源分析
- 响应式对象引用断裂:子组件
created中仅初始化一次将modelValue转为reactive赋值给block,父组件更新modelValue时未同步到block,导致两者引用分离。 - 方法拼写错误:子组件中
method应为methods,会导致updateImage无法正常触发。 - 破坏响应式关联:
updateImage中用Object.assign创建新对象替换block,原响应式对象被覆盖,后续父组件更新时无法同步到新的block对象。 - 未监听
modelValue变化:父组件更新后子组件modelValue已变更,但block未同步,导致显示旧值。
修复方案及代码修改
以下是修正后的子组件代码,核心思路是保持block为同一响应式对象,同步modelValue的变化,避免替换对象破坏响应式:
<script> import { reactive, watch } from 'vue' export default { name: 'RWImage', props: { modelValue: { type: [Array, Object], required: true } }, data() { return { block: reactive({}) }; }, created() { // 初始化同步父组件传递的modelValue到block this.syncBlock(this.modelValue) }, watch: { // 监听父组件modelValue变化,同步到子组件block modelValue: { deep: true, handler(newVal) { this.syncBlock(newVal) } }, // 监听block的深层变化,同步回父组件 block: { deep: true, handler(newVal) { // 解构创建新对象,避免父组件直接修改子组件响应式对象 this.$emit('update:modelValue', { ...newVal }) }, }, }, mounted() { EventBus.on('asset-chosen', this.updateImage); }, methods: { // 修正拼写错误:method → methods // 同步源对象属性到block,保持响应式对象引用不变 syncBlock(source) { // 先清空现有属性 Object.keys(this.block).forEach(key => delete this.block[key]) // 赋值新属性 Object.assign(this.block, source) }, updateImage(data) { if (this.$.uid === data.uid) { // 直接修改block属性,不替换整个对象,保持响应式关联 this.block.src = data.asset.secure_url this.block.cloudinaryId = data.asset.public_id this.block.cloudinary = data.asset console.log(this.block); } }, } } </script>
关键修改点说明
- 同步逻辑:通过
syncBlock方法保证block始终是同一个响应式对象,仅更新属性,避免引用断裂。 - 监听
modelValue:父组件更新时自动同步到子组件block,解决子组件数据重置问题。 - 直接修改属性:
updateImage中不再替换block对象,而是直接修改属性,确保响应式监听正常触发。 - 修正方法拼写:
methods拼写错误会导致方法无法识别,必须修正。
内容的提问来源于stack exchange,提问作者cbloss793
相关产品推荐
相关产品推荐

