vue vuedraggable实现拖拽,table表格拖拽,拖拽自定义样式
效果
1,npm install --save vuedraggable
2, import draggable from "vuedraggable";
3,
<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); },
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2020-07-27 elmentUI 选择年月日时分秒-并且只选择当前时间之后的时间