在Element UI里面我们可以通过Tree树形控件和他的属性draggable来实现
HTML结构
<el-tree
:data="data"
node-key="id"
default-expand-all
@node-drag-start="handleDragStart"
@node-drag-enter="handleDragEnter"
@node-drag-leave="handleDragLeave"
@node-drag-over="handleDragOver"
@node-drag-end="handleDragEnd"
@node-drop="handleDrop"
draggable
:allow-drop="allowDrop"
:allow-drag="allowDrag">
js
<script>
export default {
data() {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2',
children: [{
id: 11,
label: '三级 3-2-1'
}, {
id: 12,
label: '三级 3-2-2'
}, {
id: 13,
label: '三级 3-2-3'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods: {
handleDragStart(node, ev) {
console.log('drag start', node);
},
handleDragEnter(draggingNode, dropNode, ev) {
console.log('tree drag enter: ', dropNode.label);
},
handleDragLeave(draggingNode, dropNode, ev) {
console.log('tree drag leave: ', dropNode.label);
},
handleDragOver(draggingNode, dropNode, ev) {
console.log('tree drag over: ', dropNode.label);
},
handleDragEnd(draggingNode, dropNode, dropType, ev) {
console.log('tree drag end: ', dropNode && dropNode.label, dropType);
},
handleDrop(draggingNode, dropNode, dropType, ev) {
console.log('tree drop: ', dropNode.label, dropType);
},
allowDrop(draggingNode, dropNode, type) {
if (dropNode.data.label === '二级 3-1') {
return type !== 'inner';
} else {
return true;
}
},
allowDrag(draggingNode) {
return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
}
}
};
</script>
此组件样式比较顽固父级可以拖动到其他父级之中甚至子集之中且判断起来非常麻烦如果数据比较复杂且实现拖拽时较为考究可能就不太合适
Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作。
官方网站https://github.com/SortableJS/Vue.Draggable
1.安装:npm install vuedraggable
2.引入:import draggable from ‘vuedraggable’
3.注册:components: {
draggable
},
HTML
"myArray" @start="onStart" @end="onEnd">
"item" v-for="item in myArray" :key="item.id">{{item.name}}
JS
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {
drag:false,
//定义要被拖拽对象的数组
myArray:[
{people:'cn',id:10,name:'www.itxst.com'},
{people:'cn',id:20,name:'www.baidu.com'},
{people:'cn',id:30,name:'www.taobao.com'},
{people:'us',id:40,name:'www.yahoo.com'}
]
};
},
methods: {
//开始拖拽事件
onStart(){
this.drag=true;
},
//拖拽结束事件
onEnd() {
this.drag=false;
},
},
};
</script>
CSS
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable
},
data() {
return {
tolList: [
{
groupName: '获得与消耗',
children: [
{
name: '获得钻石', id: 1
},{
name: '获得装备', id: 2
}
]
}, {
groupName: '社交功能',
children: [
{
name: '战胜好友BOSS', id: 1
},{
name: '添加好友', id: 2
}
]
}, {
groupName: '互动付费',
children: [
{
name: '付费成功', id: 1
},{
name: '发起付费订单', id: 2
}
]
}
],
controlOnStart: true
}
},
methods: {
clone({ name, id }) {
return { name, id: id }
},
pullFunction() {
return this.controlOnStart ? 'clone' : true
},
start({ originalEvent }) {
this.controlOnStart = originalEvent.ctrlKey
},
getNewList() {
let a = this.tolList
console.log(a)
}
}
}
</script>
HTML
<template>
<div class="wholeList" v-for="element in tolList" :key="element.id">
<div class="leftConLi">
{{ element.name }}
</div>
<draggable
class="dragArea list-group"
:list="item.children"
:clone="clone"
:group="{ name: 'people', pull: pullFunction }"
@start="start"
>
<div v-for="element in item.children" :key="element.id" class="list-group-item">
{{ element.name }}
</div>
</draggable>
</div>
</template>
如果想要好看的拖动效果可以通过animation属性设置vue.draggable过渡效果。
vue-grid-layout是一个非常优秀的vue栅格拖动布局的组件,使用方法请参考
安装:npm install vue-grid-layout --save
引入: import VueGridLayout from ‘vue-grid-layout’
CSS
<template>
<div class="board" style="width: 100%">
<div class="home">
<grid-layout
:layout="layoutData"
:col-num="12"
:row-height="layoutHeight"
:is-draggable="dialogVisible"
:is-resizable="dialogVisible"
:is-mirrored="false"
:vertical-compact="true"
:margin="[10, 10]"
:use-css-transforms="true"
>
<grid-item v-for="(item,index) in layoutData"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
>
{{index}}
</grid-item>
</grid-layout>
</div>
</div>
</template>
JS
export default {
data() {
return {
// 布局数据
layoutData: [
{
"x": 0,
"y": 0,
"w": 1,
"h": 1,
"i": "0"
},
{
"x": 0,
"y": 1,
"w": 1,
"h": 1,
"i": "1"
},
{
"x": 0,
"y": 2,
"w": 1,
"h": 1,
"i": "2"
},
{
"x": 0,
"y": 3,
"w": 1,
"h": 1,
"i": "3"
},
{
"x": 1,
"y": 0,
"w": 1,
"h": 1,
"i": "4"
}
],
layoutConfig: {
height: 100, // 默认高度
dialogVisible: false // 是否可拖拽或改变大小
}
}
},
components: {
GridLayout,
GridItem
},
methods: {
},
created() {
}
}