weixin_58412143 2023-01-10 15:33 采纳率: 92.1%
浏览 577
已结题

vue子组件如何动态传数据给父组件?

背景:一个拖拽的页面,左侧是被拖动的模块,右侧是放置,模块的容器,每个模块是一个子组件,在容器这个父组件里循环展示,
需求:由于每个模块要设置不同宽高,所以我在每个子组件里设置了宽高然后使用this.$emit修改父组件的值,我现在设置了其中两个模块的宽高
问题:但是现在没有进行动态的更改,好像默认是B的宽高,在第一次拖动A时,要拖动两遍才是我设置A的宽高,然后无论拖动A还是B都是对的宽高;然而无论第几次在拖动B时,就是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" @getmsg="getmsg" :msg="msg" /> </template> <span class="span-error" @click="deleteItem($event, index)"> <i class="el-icon-delete del-css" />
</grid-item> </grid-layout> msg: { w: 1, h: 1 }, let mouseXY = { "x": null, "y": null }; let DragPos = { "x": null, "y": null, "w": null, "h":null, "i": null }; drag: function(e) { this.type = e.target.dataset.type let parentRect = document.getElementById('content').getBoundingClientRect(); let mouseInGrid = false; if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && ( mouseXY.y < parentRect.bottom))) { mouseInGrid = true; } if (mouseInGrid === true && (this.ViewPC.findIndex(item => item.i === 'drop')) === -1) { console.log('s.ViewPC.push') this.ViewPC.push({ x: (this.ViewPC.length * 2) % (this.colNum || 12), y: this.ViewPC.length + (this.colNum || 12), w: this.msg.w, h: this.msg.h, type: this.type, options: {}, data: [], status: 1, i: 'drop', }); } let index = this.ViewPC.findIndex(item => item.i === 'drop'); if (index !== -1) { console.log('!== -1') try { console.log('none') this.$refs.gridlayout.$children[this.ViewPC.length].$refs.item.style.display = "none"; } catch {} let el = this.$refs.gridlayout.$children[index]; el.dragging = { "top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left }; let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left); if (mouseInGrid === true) { this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, this.msg.w, this.msg.h); DragPos.i = String(index); DragPos.x = this.ViewPC[index].x; DragPos.y = this.ViewPC[index].y; DragPos.w = this.ViewPC[index].w; DragPos.h = this.ViewPC[index].h; } if (mouseInGrid === false) { this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, this.msg.w, this.msg.h); this.ViewPC = this.ViewPC.filter(obj => obj.i !== 'drop'); } } }, dragend: function(e) { let parentRect = document.getElementById('content').getBoundingClientRect(); let mouseInGrid = false; if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && ( mouseXY.y < parentRect.bottom))) { mouseInGrid = true; } if (mouseInGrid === true) { this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, DragPos.w, DragPos.h); this.ViewPC = this.ViewPC.filter(obj => obj.i !== 'drop'); 这里新增模块 this.ViewPC.push({ x: DragPos.x, y: DragPos.y, w: DragPos.w, h: DragPos.h, i: Number(DragPos.i), type: this.type, options: {}, data: [], status: 1, }); try { this.$refs.gridlayout.$children[this.ViewPC.length].$refs.item.style.display = "block"; console.log('block',this.$refs.gridlayout) } catch { } this.isPush = false this.type = null DragPos.w=null DragPos.h=null console.log('DragPos', DragPos) } },

子组件A

export default {
    name: 'Banner',
    props: ['data', 'msg'],
    data(){
      return{
      }
    },
    watch:{
      msg(newVal, oldVal) {
        console.log('banner',newVal, oldVal)
      if(JSON.stringify(newVal) !== JSON.stringify(oldVal))
      this.$emit("update:getmsg", newVal);
      },
    },
 mounted() {
   const that=this
      that.msg['w']=4.2
      that.msg['h']=6
    }
  }

子组件B

export default {
  name: 'Layout',
  props: ['data', 'msg'],
     data(){
       return{
       }
     },
     watch:{
       msg(newVal, oldVal) {
         console.log('Layout',newVal, oldVal)
       if(JSON.stringify(newVal) !== JSON.stringify(oldVal))
       this.$emit("update:getmsg", newVal);
       },
     },
  mounted() {
    const that=this
       that.msg['w']=12
       that.msg['h']=3
     }
}

  • 写回答

2条回答 默认 最新

  • 归来巨星 前端领域新星创作者 2023-01-10 17:59
    关注

    img

    img

    你看你的方法有触发嘛?没见你写语法糖

    再有我这边看你用到了 v-if 注意一下父子组件的渲染顺序,在你做数据传递的时候不排除你的子组件并没有渲染

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

报告相同问题?

问题事件

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

悬赏问题

  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?