这一篇文章引入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会识别不了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。