weixin_58412143 2023-01-11 13:38 采纳率: 90.9%
浏览 238
已结题

Vue中如何解决多个组件引用了同一个对象作为数据时,当一个组件改动了数据对象时,其他对象的数据也会随着同步改动的情况

背景:一个拖拽的页面,左侧是被拖动的模块,右侧是放置,模块的容器,每个模块是一个子组件,在容器这个父组件里循环展示,
需求:由于每个模块要设置不同宽高,所以我在每个子组件里设置了宽高然后使用this.$emit修改父组件的值,我现在设置了其中两个模块的宽高
问题:但是现在没有进行动态的更改,刚进入父组件页面时还是都打印了所有子组件修改后的值,然后导致所有组件的宽高被设置成了组件列表里最后一个组件设置的宽高,但是拖动模块之后父组件相对应改变了getmsg的值,是对的值,但是在父组件里新增模块的地方设置的宽高还是刚开始进入页面的宽高,以此类推,B组件是A组件的宽高>C组件是B组件的宽高。然后同一个模块在第二次拖动之后就是正确的宽高
父组件

<grid-layout :layout.sync="ViewPC" :col-num="12" :row-height="62" :is-resizable="false" :is-draggable="true"
            :responsive="true" :vertical-compact="true" :use-css-transforms="true" ref="gridlayout">
            <grid-item v-for="(item, index) in ViewPC" :key="index" :x="item.x" :y="item.y" :w="item.w" :h="item.h"
              :i="item.i" @resize="resizeEvent" @move="moveEvent" @resized="resizedEvent" @moved="movedEvent">
              <div v-if="index > 0" :key="index" :data-index="index"
                :class="{item: true, active: currentIndex === index }" @click="selectType(index)" style="height: 100%;">
                <template v-if="item.status && item.status === 2">
                  <div class="wait">{{ item.type }}
</template> <template v-else> <component :is="typeList[item.type]['com']" :data="item" @update:getmsg="getevent" :msg="msg" :ref="'child'+index" /> <span class="span-error" @click="deleteItem($event, index)"> <i class="el-icon-delete del-css" />
</grid-item> </grid-layout> msg: { w: 1, h: 1 }, getevent(data) { const that = this that.newMsg = data that.msg = data console.log('msgindex', data); },

子组件A

    props: ['data', 'msg'],
        newMsgDataBanner: {},
 watch: {
      newMsgDataBanner(newVal, oldVal) {
        console.log('banner', newVal, oldVal)
        if (JSON.stringify(newVal) !== JSON.stringify(oldVal));
          this.$emit('update:getmsg', newVal)
      },
    },
 created() {
      this.newMsgDataBanner=JSON.parse(JSON.stringify(this.msg))
    },
      mounted() {
      this.newMsgDataBanner.w= 4.2
      this.newMsgDataBanner.h= 6
      console.log('bannermounted', this.newMsgDataBanner, this.msg)
    }

子组件B

    props: ['data', 'msg'],
        newMsgDataLayout:{},
 watch: {
      newMsgDataLayout(newVal, oldVal) {
        console.log('Layout', newVal, oldVal)
        if (JSON.stringify(newVal) !== JSON.stringify(oldVal))
           this.$emit('update:getmsg', newVal)
      },
    },
    created() {
      this.newMsgDataLayout=JSON.parse(JSON.stringify(this.msg))
    },
    mounted() {
      this.newMsgDataLayout.w = 12
      this.newMsgDataLayout.h = 3
      console.log('Layoutmounted', this.newMsgDataLayout  , this.msg)
    }
  • 写回答

3条回答 默认 最新

  • 浪在前端 2023-01-11 13:52
    关注

    深克隆

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月20日
  • 已采纳回答 1月12日
  • 创建了问题 1月11日

悬赏问题

  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助