vue使用拖拽功能实现仓库存放货物的需求

效果:
在这里插入图片描述
代码

<template>
  <div>
    <div class="bigTitle">xxxxxxxxxxxxxx仓库拖拽系统</div>

    <div class="container2 flex-j-space-between">
      <div class="product-list">
        <div class="leftTree head">
          <div class="left">物品清单</div>
        </div>
        <div class="product-container">
          <el-collapse v-model="activeNames" @change="handleChange">
            <el-collapse-item
              class="list"
              v-for="(item,index) in products"
              :title="(index + 1) + '、' + item.name"
              :name="index"
              :key="index"
            >
              <div :draggable="true" @dragstart="onDragStart(item)">
                <span>长度:</span>
                <span>{{ item.x }}</span>
                <span></span>
                <span>宽度:</span>
                <span>{{ item.y }}</span>
                <span></span>
                <span>高度:</span>
                <span>{{ item.h }}</span>
                <span></span>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>

      <div class="delivery-cabinet">
        <div class="leftTree head">
          <div class="left">仓库</div>
        </div>
        <div style="padding-left:48px;">
          <span class="display-inline t-center" style="width:27.6%;"></span>
          <span class="display-inline t-center" style="margin-left:2%;width:18.4%;"></span>
          <span class="display-inline t-center" style="margin-left:2%;width:27.6%;"></span>
          <span class="display-inline t-center" style="margin-left:2%;width:18.4%;"></span>
        </div>
        <div class="flex-j-space-between height100">
          <div class="regionSet">
            <div>D</div>
            <div>C</div>
            <div>B</div>
            <div>A</div>
          </div>
          <div class="bigBox">
            <div
              v-for="(item,index) in cabinets"
              :key="index"
              :style="{width:item.x,height:item.y,marginRight:item.mr}"
              @drop="onDrop(item.id)"
              @dragover.prevent
              :draggable="false"
              class="smallBox"
            >
              <div
                v-for="product in item.products"
                :key="product.id"
                class="product"
                :draggable="false"
              >{{ JSON.parse(product).name }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
// import draggable from "vuedraggable";

export default {
  components: {
    // draggable
  },
  data() {
    return {
      products: [
        { id: 1, name: "苹果", x: 30, y: 34, h: 25 },
        { id: 2, name: "香蕉", x: 12, y: 10, h: 21 },
        { id: 3, name: "西瓜", x: 30, y: 50, h: 23 },
        { id: 4, name: "荔枝", x: 57, y: 12, h: 24 },
        { id: 5, name: "哈密瓜", x: 45, y: 53, h: 32 },
        { id: 6, name: "菠萝", x: 11, y: 5, h: 54 },
        { id: 7, name: "葡萄", x: 4, y: 34, h: 6 }
      ],
      cabinets: [
        {
          id: 1,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          location: [
            { name: "手表", width: 28, height: 50, x: 0, y: 0, bgClor: "red" },
            {
              name: "背包",
              width: 28,
              height: 16,
              x: 40,
              y: 40,
              bgClor: "#ff33ff"
            },
            {
              name: "缆索",
              width: 10,
              height: 80,
              x: 29,
              y: 0,
              bgClor: "yellow"
            },
            {
              name: "头盔",
              width: 28,
              height: 40,
              x: 40,
              y: 0,
              bgClor: "green"
            },
            { name: "面包", width: 33, height: 70, x: 68, y: 0, bgClor: "blue" }
          ],
          products: []
        },
        {
          id: 2,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 3,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 4,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 5,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 6,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 7,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 8,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 9,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 10,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 11,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 12,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 13,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 14,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 15,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 16,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 17,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 18,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 19,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 20,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 21,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 22,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 23,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 24,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 25,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 26,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 27,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 28,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 29,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 30,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 31,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 32,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 33,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 34,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 35,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 36,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 37,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 38,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: "2%",
          name: 1,
          products: []
        },
        {
          id: 39,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        },
        {
          id: 40,
          x: "9.2%",
          y: "24%",
          mt: 0,
          mb: 0,
          mr: 0,
          name: 1,
          products: []
        }
        // 其他柜子...
      ],
      activeNames: ["1"]
    };
  },
  methods: {
    onDragStart(product) {
      console.log("1111111", product);
      event.dataTransfer.setData("text/plain", JSON.stringify(product));
    },
    onDrop(cabinetId) {
      const productData = event.dataTransfer.getData("text/plain");
      console.log("22222222222", productData);
      const cabinet = this.cabinets.find(cabinet => cabinet.id === cabinetId);
      cabinet.products.push(productData);
      console.log("111", cabinet);
    },
    handleChange(val) {
      console.log(val);
    }
  }
};
</script>

<style scoped>
.bigTitle {
  height: 40px;
  line-height: 40px;
  font-size: 24px;
  text-align: center;
  padding-top: 5px;
}
.container2 {
  width: 100%;
  height: calc(100vh - 40px);
  padding: 10px;
  overflow: hidden;
}
.head {
  border: 0px solid black;
  width: 100%;
  height: 40px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 0 0 15px;

  border-bottom: #eff4fa 1px solid;
  .left {
    font-weight: bold;
    font-size: 16px;
    border-left: 4px blue solid;
    display: flex;
    align-items: center;
    height: 18px;
    padding-left: 10px;
  }
}
.product-list {
  width: 400px;
  border: 1px solid #f0f0f0;
  height: 100%;
}
.delivery-cabinet {
  height: 100%;
  flex: 1;
}

.product-list h2,
.delivery-cabinet h2 {
  font-size: 24px;
  margin-bottom: 10px;
}

.product-container {
  /* 
  padding: 10px;
  border-radius: 4px; */
}

.product {
  padding: 10px;
  margin-bottom: 8px;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  cursor: move;
}

.cabinet-container {
  background-color: #f2f2f2;
  padding: 10px;
  border-radius: 4px;
}

.cabinet-slot {
  padding: 10px;
  margin-bottom: 8px;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.slot-number {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 5px;
}

.slot-content {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.slot-content .product {
  padding: 6px 8px;
  background-color: #eee;
}
.regionSet {
  width: 45px;
  height: 100%;
  margin-top: 10px;
}
.regionSet div {
  height: 23%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bigBox {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  height: calc(100% - 40px);
  width: calc(100% - 50px);
  padding: 10px 10px;
  padding-left: 0px;
}
.smallBox {
  border: 1px solid green;
}
</style>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue实现卡片拖拽功能可以使用vue-grid-layout插件,它是一个基于Gridster.js封装的Vue组件,支持拖拽、排序、缩放等功能。下面是一个简单的示例: 1. 安装vue-grid-layout插件: ``` npm install vue-grid-layout --save ``` 2. 在Vue组件中引入并注册vue-grid-layout组件: ``` <template> <div> <vue-grid-layout :layout="layout" :col-num="12" :row-height="30" :is-draggable="true" :is-resizable="true" :vertical-compact="false" :margin="[10, 10]"> <div v-for="item in items" :key="item.id" :data-grid="{x: item.x, y: item.y, w: item.w, h: item.h}"> <div class="card">{{ item.text }}</div> </div> </vue-grid-layout> </div> </template> <script> import VueGridLayout from 'vue-grid-layout' export default { components: { VueGridLayout }, data() { return { layout: [ { x: 0, y: 0, w: 4, h: 2 }, { x: 4, y: 0, w: 4, h: 2 }, { x: 8, y: 0, w: 4, h: 2 }, { x: 0, y: 2, w: 4, h: 2 }, { x: 4, y: 2, w: 4, h: 2 }, { x: 8, y: 2, w: 4, h: 2 }, { x: 0, y: 4, w: 4, h: 2 }, { x: 4, y: 4, w: 4, h: 2 }, { x: 8, y: 4, w: 4, h: 2 } ], items: [ { id: 1, text: 'Card 1', x: 0, y: 0, w: 4, h: 2 }, { id: 2, text: 'Card 2', x: 4, y: 0, w: 4, h: 2 }, { id: 3, text: 'Card 3', x: 8, y: 0, w: 4, h: 2 }, { id: 4, text: 'Card 4', x: 0, y: 2, w: 4, h: 2 }, { id: 5, text: 'Card 5', x: 4, y: 2, w: 4, h: 2 }, { id: 6, text: 'Card 6', x: 8, y: 2, w: 4, h: 2 }, { id: 7, text: 'Card 7', x: 0, y: 4, w: 4, h: 2 }, { id: 8, text: 'Card 8', x: 4, y: 4, w: 4, h: 2 }, { id: 9, text: 'Card 9', x: 8, y: 4, w: 4, h: 2 } ] } } } </script> <style> .card { background-color: #eee; padding: 10px; } </style> ``` 3. 在Vue组件中使用vue-grid-layout组件,并设置相关属性和回调函数。 其中,`layout`为卡片的布局数据,`items`为卡片数据,可以设置卡片的大小、位置、内容等。`col-num`为列数,`row-height`为行高,`is-draggable`和`is-resizable`分别为是否可拖拽和缩放,`vertical-compact`为是否自动间隙调整,`margin`为卡片之间的间距。 通过以上步骤,就可以在Vue实现卡片拖拽功能了。如果需要更多定制化的功能,可以参考vue-grid-layout的文档进行配置。 ### 回答2: Vue.js是一个流行的JavaScript框架,提供了许多便捷的工具和组件,可以帮助我们快速构建交互式的Web应用程序。在Vue实现卡片拖拽功能可以通过使用Vue的指令和事件来实现。 首先,我们可以使用Vue的自定义指令来实现拖拽功能。我们可以创建一个名为`v-draggable`的指令,并在其中添加适当的事件监听器。在指令的`bind`和`update`钩子函数中,我们可以添加`mousedown`、`mousemove`和`mouseup`事件的监听器来跟踪鼠标的位置,并计算卡片的偏移量。在`bind`钩子函数中,我们还可以将卡片的初始位置保存起来,以便在拖拽结束时进行处理。 接下来,我们可以在需要拖拽功能的卡片元素上添加`v-draggable`指令,并传入相应的参数。例如,我们可以将卡片的位置信息传递给指令,使其知道卡片应该在哪个位置进行拖拽。这可以通过在指令的`bind`钩子函数中将卡片的位置信息保存到指令实例的属性中来实现。 最后,我们还可以在指令中添加一些逻辑,以处理拖拽结束时的操作。例如,我们可以在`mouseup`事件的监听器中更新卡片的位置信息,并触发相应的事件来通知其他组件或监听器。 通过以上步骤,我们可以在Vue实现卡片拖拽功能。并且,由于Vue的响应式系统,我们可以很方便地更新卡片的位置信息,并对其进行相应的处理。这使得卡片拖拽功能更加灵活和易于扩展。 ### 回答3: Vue实现卡片拖拽功能可以通过Vue的事件绑定和动态样式来实现。以下是一个简单的示例代码: 首先,在Vue的data中定义一个卡片对象数组,包含每个卡片的位置信息,如left和top: ```javascript data() { return { cards: [ { id: 1, left: 0, top: 0 }, { id: 2, left: 100, top: 0 }, { id: 3, left: 200, top: 0 } ], draggingCardId: null, offsetX: 0, offsetY: 0 }; }, ``` 然后,通过v-for指令渲染卡片列表,并为每个卡片绑定mousedown、mousemove、mouseup事件: ```html <div id="app"> <div class="card" v-for="card in cards" :key="card.id" :style="{ left: card.left + 'px', top: card.top + 'px' }" @mousedown="startDragging(card.id, $event)"> Card {{ card.id }} </div> </div> ``` 在methods中,定义startDragging方法用于设置拖拽起点和拖拽的卡片ID,还有onDrag和stopDragging方法用于设置卡片位置和清空拖拽信息: ```javascript methods: { startDragging(cardId, event) { this.draggingCardId = cardId; this.offsetX = event.clientX - this.cards[cardId - 1].left; this.offsetY = event.clientY - this.cards[cardId - 1].top; document.addEventListener('mousemove', this.onDrag); document.addEventListener('mouseup', this.stopDragging); }, onDrag(event) { if (this.draggingCardId !== null) { this.cards[this.draggingCardId - 1].left = event.clientX - this.offsetX; this.cards[this.draggingCardId - 1].top = event.clientY - this.offsetY; } }, stopDragging() { this.draggingCardId = null; document.removeEventListener('mousemove', this.onDrag); document.removeEventListener('mouseup', this.stopDragging); } } ``` 通过上述代码,我们就可以实现拖拽卡片的功能。当鼠标按下时,调用startDragging方法设置起点和卡片ID,然后在mousemove事件中通过onDrag方法不断更新卡片的位置,当鼠标释放时,调用stopDragging方法将拖拽信息清空。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值