vue.draggable拖拽列表,更换元素位置

这一篇文章引入vue.draggable拖拽列表他,有动画效果更流畅。

vue.draggable官网

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>vue.draggable拖拽列表,更换元素位置</title>
 <!--引入 element-ui 的样式,-->
 <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
 <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
 <!-- 引入element 的组件库-->
 <script src="https://unpkg.com/element-ui/lib/index.js"></script>
 <script src="https://www.itxst.com/package/sortable/Sortable.min.js"></script>
 <script src="https://www.itxst.com/package/vuedraggable/vuedraggable.umd.min.js"></script>
 <style>
 * {
 margin: 0;
 padding: 0;
 }
 #app {
 margin: 50px;
 }
 .item {
 padding: 8px 12px;
 border-radius: 3px;
 transition: background-color 0.3s;
 margin-bottom: 4px;
 position: relative;
 border: 1px solid #000;
 background-color: #fff;
 }
 .item .add {
 display: none;
 justify-content: center;
 align-items: center;
 position: absolute;
 font-size: 18px;
 color: #2c66ff;
 border-radius: 50%;
 left: -10px;
 top: 30%;
 }
 .item .icon {
 color: red;
 font-size: 30px;
 cursor: pointer;
 margin-bottom: 10px;
 }
 /* 拖拽时候的样式 */
 .item.chosen {
 background: #fff;
 filter: drop-shadow(0px 8px 24px rgba(18, 19, 20, 0.18));
 }
 .item.chosen .add {
 display: block;
 }
 /* 拖拽到哪里的样式 */
 .item.ghost {
 position: relative;
 border-top-color: #2c66ff;
 }
 .item.ghost .add {
 display: none;
 }
 </style>
</head>
<body>
 <div id="app">
 <!-- chosen-class写法要规范,如果写chosenClass对应的class会识别不了 -->
 <draggable v-model="summaryArr" force-fallback="true" group="id" animation="300" @start="onStartDraggable"
 @end="onEndDraggable" handle=".drag-wrap" chosen-class="chosen" ghost-class="ghost">
 <transition-group>
 <div v-for="(item, index) in summaryArr" :key="index" class="item">
 <i class="add el-icon-circle-plus-outline"></i>
 <div class="icon-wrap" @click.stop>
 <!-- 拖拽icon -->
 <i class="icon el-icon-rank drag-wrap"></i>
 </div>
 <div class="item-con">{{item.text}}</div>
 </div>
 </transition-group>
 </draggable>
 </div>
 <script>
 new Vue({
 el: '#app',
 data() {
 return {
 // 源数据
 summaryArr: [
 {
 id: '1',
 text: '内容1'
 },
 {
 id: '2',
 text: '内容2'
 },
 {
 id: '3',
 text: '内容3'
 },
 {
 id: '4',
 text: '内容4'
 },
 {
 id: '5',
 text: '内容5'
 }
 ],
 // 深拷贝源数据
 summaryArrCopy: [],
 // 拖拽
 drag: false,
 }
 },
 created() {
 // 深拷贝最新的源数据,目的是为了判断拖拽的位置是否有没有更换,没有更换就不调接口
 this.summaryArrCopy = JSON.parse(JSON.stringify(this.summaryArr));
 },
 methods: {
 // 开始拖拽
 onStartDraggable() {
 this.drag = true;
 },
 // 拖拽完毕,调取接口
 async onEndDraggable() {
 // 是否更换过位置,如果拖拽过后还是原位置,则不掉接口
 const isChangePosition = this.summaryArr.some((item, index) => {
 if (item.id === this.summaryArrCopy[index].id) {
 return false;
 } else {
 return true;
 }
 });
 this.drag = false;
 if (isChangePosition) {
 // 深拷贝最新的源数据,目的是为了判断拖拽的位置是否有没有更换,没有更换就不调接口
 this.summaryArrCopy = JSON.parse(JSON.stringify(this.summaryArr));
 // 调取接口
 console.log(this.summaryArr, '排序过后的数据')
 this.$message({
 message: '排序成功!',
 type: 'success'
 });
 }
 },
 }
 })
 </script>
</body>
</html>

注意事项:

1.drag-wrap放在哪个元素上则该元素会有拖拽功能,我这个demo是放在了拖拽的icon上面,需要更大的拖拽范围可以放在item上面。
2.在标签上的自定义属性需要用“-”分割,不要用驼峰。需要这样写:chosen-class="chosen",不能用chosenClass="chosen",如果写chosenClass对应的class会识别不了

作者:我的一个道姑朋友原文地址:https://segmentfault.com/a/1190000043870462

%s 个评论

要回复文章请先登录注册