效果图
安装
npm install --save vuedraggable || yarn add vuedraggable
引入组件
//导入draggable组件
import draggable from "vuedraggable";
//注册draggable组件
components: {
draggable
},
组件使用(不含后台数据接收返回处理)
<template>
<!--使用draggable组件-->
<div class="dragCol" ref="dragCol">
<div class="dragItem dragHeader" ref="dragHeader">
<el-checkbox id="dragAll" v-model="checkAll" :indeterminate="isIndeterminate" @change="handleAllChecked"
class="checkbox-common">{{
this.vmodel.label
}}
</el-checkbox>
<span class="svgIcon">
<!-- <svg-icon icon-class="sort" style="cursor: pointer"></svg-icon> -->
</span>
</div>
<!-- <div class="dragMain" style="height:dragMainHeight;"> -->
<div class="dragMain" ref="dragMain" :style="{ height: mainHeight }">
<draggable v-model="testList"
:options="{ group: { name: 'itxst', pull: 'clone' }, sort: true }" animation="300"
:move="onMove" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass"
@input="handleListChange($event)">
<transition-group>
<div class="dragItem canDragon" v-for="(item, index) in testList" :key="index" ref="dragItem">
<el-checkbox v-model="item.checked" :disabled="item.locked" name="checkItem"
@change="handleChecked(item, $event)" class="checkbox-common"> {{ item.displayName
}}</el-checkbox>
<span class="svgIcon">
<img :src="iconSort" alt="" width="100%" />
</span>
</div>
</transition-group>
</draggable>
</div>
</div>
</template>
<script>
//导入draggable组件
import draggable from "vuedraggable";
export default {
//注册draggable组件
name: "ct-dragSort",
components: {
draggable
},
props: {
vmodel: Object,
api: String
},
data() {
return {
iconSort: require("../../../assets/sort.png"),
drag: false,
checkAll: true,
//定义要被拖拽对象的数组
testList: [],
mainHeight: 500,
isIndeterminate: true
};
},
watch: {
testList: {
// 监听事件,监听复选框是否全部选中,全部选中则全选的复选框勾选上
handler(val) {
var i = 0;
this.testList.forEach(item => {
if (item.checked === true) {
i++;
}
if (i === this.testList.length) {
this.checkAll = true;
this.isIndeterminate = false
} else {
this.checkAll = false;
if (i > 0 && i < this.testList.length) {
this.isIndeterminate = true
} else {
this.isIndeterminate = false
}
}
});
},
deep: true
}
},
created() {
this.$nextTick(function () {
if (typeof this.vmodel === 'undefined') {
this.model = this.loaderObj.DragSort(this.source);
}
else {
this.model = this.vmodel;
this.testList = this.vmodel.dragList;
}
});
this.testList.forEach(item => {
// 处理后端传过来的数据,如果没有可以判断是否勾选复选框的字段,则需给数据作处理,加上一个isChecked字段,判断复选框勾选
this.$set(item, "checked", false); // 添加判断的字段
});
},
mounted() {
this.$nextTick(() => {
this.sjcount();
});
},
methods: {
sjcount() {
this.$nextTick(() => {
// const height = window.innerHeight;
let screenHeight = document.body.clientHeight;
let dragHeaderHeight = this.$refs.dragHeader.offsetHeight;
let dragMainHeight = this.$refs.dragMain.style.height;
dragMainHeight =
screenHeight - dragHeaderHeight - 26 - 8 - 44 - 40;
this.mainHeight = dragMainHeight + "px";
let num = this.testList.length
let dragItemAll = 44.68 * num;
if (dragMainHeight > dragItemAll) {
this.mainHeight = dragItemAll + "px";
this.$refs.dragMain.style.overflowY = 'hidden'
} else {
this.mainHeight = dragMainHeight + "px";
this.$refs.dragMain.style.overflowY = 'overlay'
}
});
},
// 更新位置
handleListChange(event) {
this.testList = event;
this.testList.forEach((item, i) => {
this.model.dragList.splice(i, 1, item);
});
},
//move回调方法
onMove(e, originalEvent) { },
//开始拖拽事件
onStart() {
this.drag = true;
},
//拖拽结束事件
onEnd() {
this.drag = false;
},
handleAllChecked(v) {
// 实现全选,反选(点击会传递true或者false过来)
this.testList.map(item => {
if (!item.locked) {
item.checked = v;
} else {
return false;
}
});
this.vmodel.draglist = this.testList;
},
handleChecked(item, e) {
// 单个选中
item.checked = e;
this.vmodel.draglist = this.testList;
}
}
};
</script>
<style scoped>
/*定义要拖拽元素的样式*/
.ghostClass {
background-color: #fff !important;
}
.chosenClass {
background-color: #ccc !important;
opacity: 1 !important;
}
/* 拖拽过程 */
.dragClass {
background-color: #fff !important;
opacity: 1 !important;
box-shadow: none !important;
outline: none !important;
background-image: none !important;
}
.dragCol {
width: 100%;
flex: 1;
border-radius: 5px;
float: left;
margin-top: -5px;
}
.dragCol+.dragCol {
margin-left: 10px;
}
.dragItem {
width: auto;
padding: 12px 10px;
margin: 0 -5px;
border-bottom: solid 1px #eee;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.dragItem:hover {
background-color: #f5f7fa;
cursor: move;
}
.dragItem+.dragItem {
border-top: none;
}
#dragAll {
color: #909399;
font-weight: 700;
}
.svgIcon {
width: 16px;
text-align: center;
cursor: pointer;
}
.dragHeader {}
.dragMain {
overflow-y: overlay;
overflow-x: hidden;
}
/* .checkbox-common>>>span.el-checkbox__label {
padding-left: 30px;
} */
</style>
官方文档例子
<template>
<div>
<div>{{drag?'拖拽中':'拖拽停止'}}</div>
<!--使用draggable组件-->
<draggable v-model="myArray" chosenClass="chosen" forceFallback="true" group="people" animation="1000" @start="onStart" @end="onEnd">
<transition-group>
<div class="item" v-for="element in myArray" :key="element.id">{{element.name}}</div>
</transition-group>
</draggable>
</div>
</template>
<style scoped>
/*被拖拽对象的样式*/
.item {
padding: 6px;
background-color: #fdfdfd;
border: solid 1px #eee;
margin-bottom: 10px;
cursor: move;
}
/*选中样式*/
.chosen {
border: solid 2px #3089dc !important;
}
</style>
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {
drag:false,
//定义要被拖拽对象的数组
myArray:[
{people:'cn',id:1,name:'www.itxst.com'},
{people:'cn',id:2,name:'www.baidu.com'},
{people:'cn',id:3,name:'www.taobao.com'},
{people:'us',id:4,name:'www.google.com'}
]
};
},
methods: {
//开始拖拽事件
onStart(){
this.drag=true;
},
//拖拽结束事件
onEnd() {
this.drag=false;
},
},
};
</script>
效果图
附上官方文档地址:vue.draggable中文文档 - itxst.com