vue vuedraggable实现拖拽,table表格拖拽,拖拽自定义样式

发布时间 2023-07-27 15:01:49作者: shuihanxiao

 

效果

 

1,npm install --save vuedraggable

2,   import draggable from "vuedraggable";

3,   

 components: {
    draggable,
  },
 
4,
 <table cellspacing="0" cellpadding="0" border="0" class="el-table__body" style="width: 100%;">

                    <!--  @end="onEnd_all" end-->
                    <tbody>
                      <draggable :group="groupName" v-model="sortList" @end="end" @start="start" @update="upd"
                        :forceFallback="true" dragClass="dragClass" :move="onMove" fallbackClass="fallbackClass"
                        chosenClass="chosenClass" ghostClass="ghostClass" filter=".undraggable">
                        <tr class="el-table__row" v-for="(item, index) in sortList" :key="index"
                          style="position: relative;cursor: pointer;line-height: 25px; margin: 5px 0; border-bottom: 1px solid #EBEEF5;display: flex;">
                          <td rowspan="1" colspan="1" class="el-table_31_column_299">
                            <div class="drgText undraggable" style="padding: 12px ; font-size: 14px;color: #323233;width:180px;">
                              {{ index + 1 }}
                            </div>
                          </td>
                          <td rowspan="1" colspan="1" class="el-table_31_column_300  ">
                            <div class="drgText undraggable" style="padding: 12px ; font-size: 14px;color: #323233;width:180px;">
                              {{ item.goodsName }}</div>
                          </td>
                          <td rowspan="1" colspan="1" class="el-table_31_column_300  ">
                            <div class="drgText undraggable" style="padding: 12px ; font-size: 14px;color: #323233;width:180px;">
                              {{ item.goodsName }}</div>
                          </td>
                          <td rowspan="1" colspan="1" class="el-table_16_column_215 is-right ">
                            <div class="cell">
                              <button data-v-564301d8="" type="button"
                                class="el-button el-button--text el-button--mini undraggable"><!----><!----><span>商品排序</span></button>
                              <button data-v-564301d8="" type="button" class="el-button el-button--text el-button--mini">
                                <img src="@/assets/login_images/sort.png" alt="" style="width: 20px;height: 14px;">
                              </button>

                              <button data-v-564301d8="" type="button"
                                class="el-button el-button--text el-button--mini undraggable"><!----><!----><span>查看详情</span></button>
                              <!----> <button @click="doDeleteMeu" data-v-564301d8="" type="button"
                                class="el-button el-button--text el-button--mini undraggable"><!----><!----><span>删除</span></button>
                              <!----> <button data-v-564301d8="" @click="editMenu" type="button"
                                class="el-button el-button--text el-button--mini undraggable"><!----><!----><span>编辑</span></button>
                            </div>
                          </td>
                        </tr>
                      </draggable>
                    </tbody>
                  </table>
 //定义要被拖拽对象的数组
      cacheSelected: [],
      sortList: [{ "goodsPrice": 0.01, "discountPrice": null, "specPrice": 0.01, "isSpecification": true, "specificationList": [{ "id": "1676503573694750721", "title": "500ML", "subList": [{ "id": "1676503573770248194", "sellerGoodsSpecificationId": "1676503573694750721", "isSetPrice": true, "content": "测试1", "price": 0.01 }, { "id": "1676503573837357058", "sellerGoodsSpecificationId": "1676503573694750721", "isSetPrice": false, "content": "0", "price": null }] }], "discountBtn": false, "id": "1672775854333554689", "sellerId": "1672769733264441345", "goodsGroupId": "1672775645645959170", "goodsClassifyId": "1672447310354739201", "goodsName": "咩咩奶茶1", "goodsClassifyName": "饮品>奶茶>水果茶>果茶", "goodsGroupName": "奶茶", "userFlag": true, "packFee": 0.00, "saleNum": "7" }, { "goodsPrice": 0.00, "discountPrice": null, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": false, "id": "1672777343482933250", "sellerId": "1672769733264441345", "goodsGroupId": "1672775645645959170", "goodsClassifyId": "1672447310354739201", "goodsName": "波波奶茶", "goodsClassifyName": "饮品>奶茶>水果茶>果茶", "goodsGroupName": "奶茶", "userFlag": true, "packFee": 0.00, "saleNum": "439" }, { "goodsPrice": 0.01, "discountPrice": null, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": false, "id": "1673244752022441986", "sellerId": "1672769733264441345", "goodsGroupId": "1673244543792025601", "goodsClassifyId": "1672447310354739201", "goodsName": "咩咩奶茶", "goodsClassifyName": "饮品>奶茶>水果茶>果茶", "goodsGroupName": "咩咩", "userFlag": true, "packFee": 0.00, "saleNum": "29" }, { "goodsPrice": 0.01, "discountPrice": null, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": false, "id": "1673880447608090625", "sellerId": "1672769733264441345", "goodsGroupId": "1672775645645959170", "goodsClassifyId": "1672447310354739201", "goodsName": "西瓜汁", "goodsClassifyName": "饮品>奶茶>水果茶>果茶", "goodsGroupName": "奶茶", "userFlag": true, "packFee": 0.00, "saleNum": "34" }, { "goodsPrice": 0.02, "discountPrice": 0.01, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": true, "id": "1676888256799932417", "sellerId": "1672769733264441345", "goodsGroupId": "1672775645645959170", "goodsClassifyId": "1672447256323715074", "goodsName": "手打柠檬茶", "goodsClassifyName": "饮品>奶茶>水果茶", "goodsGroupName": "奶茶", "userFlag": true, "packFee": 0.00, "saleNum": "5" }, { "goodsPrice": 10.00, "discountPrice": null, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": false, "id": "1678322098249744386", "sellerId": "1672769733264441345", "goodsGroupId": "1673244543792025601", "goodsClassifyId": "1672447310354739201", "goodsName": "起步价", "goodsClassifyName": "饮品>奶茶>水果茶>果茶", "goodsGroupName": "咩咩", "userFlag": true, "packFee": 0.00, "saleNum": "0" }, { "goodsPrice": 30.00, "discountPrice": 25.00, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": true, "id": "1680097021129220097", "sellerId": "1672769733264441345", "goodsGroupId": "1680097019984175106", "goodsClassifyId": "1673596150881738753", "goodsName": "招牌鱼香肉丝", "goodsClassifyName": "经典产品>汉堡>原味板烧鸡腿堡", "goodsGroupName": "热菜", "userFlag": true, "packFee": 0.01, "saleNum": "0" }, { "goodsPrice": 50.00, "discountPrice": 45.00, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": true, "id": "1680097021217300481", "sellerId": "1672769733264441345", "goodsGroupId": "1680097020353273858", "goodsClassifyId": "1673596150881738753", "goodsName": "超级巨无霸", "goodsClassifyName": "经典产品>汉堡>原味板烧鸡腿堡", "goodsGroupName": "汉堡", "userFlag": true, "packFee": 2.00, "saleNum": "0" }, { "goodsPrice": 60.00, "discountPrice": 55.00, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": true, "id": "1680097021301186561", "sellerId": "1672769733264441345", "goodsGroupId": "1680097020479102978", "goodsClassifyId": "1673596150881738753", "goodsName": "甜品大拼盘", "goodsClassifyName": "经典产品>汉堡>原味板烧鸡腿堡", "goodsGroupName": "甜品", "userFlag": true, "packFee": 3.00, "saleNum": "0" }, { "goodsPrice": 10.00, "discountPrice": 8.00, "specPrice": null, "isSpecification": false, "specificationList": [], "discountBtn": true, "id": "1680097021380878338", "sellerId": "1672769733264441345", "goodsGroupId": "1680097020600737794", "goodsClassifyId": "1673596150881738753", "goodsName": "香辣鸡翅", "goodsClassifyName": "经典产品>汉堡>原味板烧鸡腿堡", "goodsGroupName": "小吃", "userFlag": true, "packFee": 0.50, "saleNum": "0" }],
      menuName: '',//新增菜单名称
      dialogVisibleMenu: false,
      updateMenuoading: false,
      menuDialogName: '新增菜单',

      destIndex: -1,//要交换的目标元素下标
      srcIndex: -1,//要交换的起始元素下标

5,  mouted 内调用initSort

 initSort() {
      const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
      // const sortable = new Sortable(el, options);
      // 根据具体需求配置options配置项
      const sortable = new Sortable(el, {
        onEnd: (evt) => { // 监听拖动结束事件
          console.log(this) // this是当前vue上下文
          console.log(evt.oldIndex) // 当前行的被拖拽前的顺序
          console.log(evt.newIndex) // 当前行的被拖拽后的顺序
          // 这里就可以写我们需要传给后台的逻辑代码
          // 我们有了 evt.oldIndex 和 evt.newIndex 这两个参数做索引,我们可以根据绑定在表格上面的 data 这个 Array 找到两个相应的记录。就可以针对数据进行操作啦。
          // 下面将拖拽后的顺序进行修改
          const currRow = this.list.splice(evt.oldIndex, 1)[0]
          this.list.splice(evt.newIndex, 0, currRow)
          const newData = []
          this.list.forEach((item, index) => {
            newData[index] = {
              id: item.id,
              rank: index + 1
            }
          })
          // 下面是将排序结果更新到数据库中,根据自己项目的逻辑进行实现即可。
          const data = {
            id: this.$route.params.id,
            datas: {
              streams: newData
            }
          }
          this.$store
            .dispatch('user/setMultiSort', data)
            .then((res) => {
              if (res.code === 200) {
                this.$message.success('排序修改成功')
                // 修改成功后重新获取列表数据更新
                this.getMultiLiveList()
              } else {
                this.$message.error('排序修改失败')
              }
            })
            .catch((e) => {
              console.log(e)
            })
        }
      })
    },

6,  

 upd(e, u) {
      console.log('update', e)
    },
    start(e) {
      this.srcIndex = e.oldIndex;//开始拖拽的元素下标(位置)
      console.log("srcIndex==来源下标" + this.srcIndex)
    },
    end({ to, from, item, clone, oldIndex, newIndex }) {//松开鼠标时触发
      console.log('end111')
      console.log("from" + from)
      console.log(from)
      console.log("to" + to)
      console.log(to)
      console.log("item" + item)
      console.log(item)
      console.log("endIndex==结束下标" + this.destIndex)
      console.log("oldIndex==oldIndex" + this.oldIndex)
      console.log("newIndex==newIndex" + this.newIndex)
      //开始拖拽的元素和拖拽目的元素交换位置
      // let lastItem = this.sortList[this.destIndex];
      // let firstItem = this.sortList[this.srcIndex];
      // this.sortList.splice(this.srcIndex, 1, lastItem)
      // this.sortList.splice(this.destIndex, 1, firstItem)
      // this.destIndex = -1;
    },
    onMove(e, originalEvent) { //占位图移动到目标位置时触发
      console.log('move11')
      this.destIndex = e.draggedContext.futureIndex; //每次拖拽移动记住当前拖拽到的位置
      return false;
    },

7,  

// 排序表格
.is-right {
  position: absolute;
  right: 0;
  top: 6px;
  padding-right: 12px;
}

.sortHead .drgText {
  font-size: 14px;
  color: #323233;
  font-weight: 700;
}

.is-right .el-button {
  cursor: pointer !important;
}

//拖动排序样式
.dragClass {
  border-radius: 4px;
  opacity: 1;
  border: 5px solid green !important;
}

.fallbackClass {

  border-radius: 4px;
  opacity: 1;
  border: 1px solid #adc1ef !important;
}

.chosenClass {
  color:#fff !important;
  border-radius: 4px;
  opacity: 1 !important;
  background:rgb(248, 249, 250);
  // border: 5px solid pink;
}

.ghostClass {
  opacity: 0.7 !important;

  // border: 5px solid saddlebrown;
}

.draggable {
  cursor: pointer;
  width: 141px;
  height: 100px;
}</style>

结束

===================

详细讲解(以下紧看文案和使用方式即可,非上面效果图的代码)

<ul class="projset-content">

<!--拖拽控件-->
<!--
handle:只有当鼠标移动到css为dargBtn类的元素上才能拖动
filter:设置了undraggable样式的元素不允许拖动
chosenClass:被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
ghostClass:设置拖动元素的占位符类名(占位的样式),你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
dragClass:拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
fallbackClass:克隆的DOM元素的类名
draggable:指定哪些元素是可以被拖动的
-->
<draggable
v-model="imgList"
:forceFallback="true"
:move="onMove"
:list="imgList"
handle=".dargBtn"
:animation="0"
filter=".undraggable"
fallbackClass="fallbackClass"
ghostClass="ghostClass"
chosenClass="chosenClass"
dragClass="dragClass"
@end="end"
@start="start"
:sort="isSort"
@update="upd"
>
<li v-for="(item, index) in imgList" :key="index" :class="canEdit ? 'draggable' : 'undraggable'">
<div class="dargBtn">
<!-- <svg-icon icon-class="drag" /> -->
</div>
<img :src="item.path" alt="">
<span>{{item.name}}</span>
</li>
</draggable>
</ul>

 

=====================

除此以外,想拖拽后直接拿到最后排序完之后的数组,可以使用下面的方法

 onEnd_all() {
      console.log("this.cacheSelected:", this.cacheSelected);
      console.log("this.allCache:", this.sortList);
      console.log("this.itemList:", this.itemList);
    },
 
<draggable :group="groupName" v-model="sortList" @end="end" @start="start" @update="upd"
                        :forceFallback="true" dragClass="dragClass" :move="onMove" fallbackClass="fallbackClass"
                        chosenClass="chosenClass" ghostClass="ghostClass" filter=".undraggable">
 
上面所有的拖拽函数清空只用 
@end="onEnd_all"
 
也就是
 <draggable :group="groupName" v-model="sortList" @end="onEnd_all"
                        :forceFallback="true" dragClass="dragClass"  fallbackClass="fallbackClass"
                        chosenClass="chosenClass" ghostClass="ghostClass" filter=".undraggable">