在ant design vue中实现拖拽换位的方法目前只有树状控件可以实现
但是有时候我们的需求可能是需要复选框实现拖拽,点击控制表头的显示与隐藏下面我直接给出一个例子,
这是官网给的拖拽例子
<template>
<a-tree
class="draggable-tree"
:default-expanded-keys="expandedKeys"
draggable
:tree-data="gData"
@dragenter="onDragEnter"
@drop="onDrop"
/>
</template>
<script>
const x = 3;
const y = 2;
const z = 1;
const gData = [];
const generateData = (_level, _preKey, _tns) => {
const preKey = _preKey || '0';
const tns = _tns || gData;
const children = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
tns.push({ title: key, key });
if (i < y) {
children.push(key);
}
}
if (_level < 0) {
return tns;
}
const level = _level - 1;
children.forEach((key, index) => {
tns[index].children = [];
return generateData(level, key, tns[index].children);
});
};
generateData(z);
export default {
data() {
return {
gData,
expandedKeys: ['0-0', '0-0-0', '0-0-0-0'],
};
},
methods: {
onDragEnter(info) {
console.log(info);
// expandedKeys 需要受控时设置
// this.expandedKeys = info.expandedKeys
},
onDrop(info) {
console.log(info);
const dropKey = info.node.eventKey;
const dragKey = info.dragNode.eventKey;
const dropPos = info.node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (data, key, callback) => {
data.forEach((item, index, arr) => {
if (item.key === key) {
return callback(item, index, arr);
}
if (item.children) {
return loop(item.children, key, callback);
}
});
};
const data = [...this.gData];
// Find dragObject
let dragObj;
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
if (!info.dropToGap) {
// Drop on the content
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到尾部,可以是随意位置
item.children.push(dragObj);
});
} else if (
(info.node.children || []).length > 0 && // Has children
info.node.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到尾部,可以是随意位置
item.children.unshift(dragObj);
});
} else {
let ar;
let i;
loop(data, dropKey, (item, index, arr) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
this.gData = data;
},
},
};
</script>
这是我写给大家的例子
<template>
<div class="card-container">
<div class="defineList">
<a-row>
<a-col :span="24">
<a-dropdown v-if="data.length > 0" v-model="visible" :trigger="['click']" class="selectMenuCont" placement="bottomLeft">
<a class="ant-dropdown-link" @click="e => e.preventDefault()">
管理显示信息
<a-icon type="down" />
</a>
<a-menu slot="overlay">
<a-tree
class="paperCheck"
v-model="checkedColumn"
checkable
:tree-data="columns"
:default-expanded-keys="expandedKeys"
draggable
@dragenter="onDragEnter"
@drop="onDrop"
/>
<a-menu-divider />
<a-menu-item>
<a-button @click="handleMenuClickAll_comm">{{ selectText }}</a-button>
<a-button @click="handleMenuClick_comm">确定</a-button>
<a-button @click="colseMenuClick">取消</a-button>
</a-menu-item>
</a-menu>
</a-dropdown>
</a-col>
</a-row>
<div>
<a-table bordered :loading="loading" ref="table" :columns="selectedColumns" :data-source="data" :pagination="false"> </a-table>
</div>
</div>
</div>
</template>
<script>
const data = [];
for (let i = 0; i < 5; i++) {
data.push({
key: i,
uuid: `小灰灰`,
name: `平底锅`,
code: `2010-01-06`,
sortNum: `¥16,340.20`,
squarePerPage: `小白`,
pathName: `水波`,
psPath: `现金`,
Path: `国家`
});
}
export default {
name: 'PaperPagedList',
data() {
return {
columns: [],
selectText: '全选',
checkedColumn: [],
selectedColumns: [],
expandedKeys: [],
loading: false,
data,
visible: false
};
},
mounted() {
this.columns = [
{
ellipsis: true,
title: this.i18nRender('喜羊羊'),
dataIndex: 'uuid',
key: 'uuid'
},
{
ellipsis: true,
title: this.i18nRender('懒羊羊'),
dataIndex: 'name',
key: 'name'
},
{
ellipsis: true,
title: this.i18nRender('美羊羊'),
dataIndex: 'code',
key: 'code'
},
{
ellipsis: true,
title: this.i18nRender('沸羊羊'),
dataIndex: 'sortNum',
key: 'sortNum'
},
{
ellipsis: true,
title: this.i18nRender('慢羊羊'),
dataIndex: 'squarePerPage',
key: 'squarePerPage'
},
{
ellipsis: true,
title: this.i18nRender('暖羊羊'),
dataIndex: 'pathName',
key: 'pathName'
},
{
ellipsis: true,
title: this.i18nRender('灰太狼'),
dataIndex: 'psPath',
key: 'psPath'
},
{
ellipsis: true,
title: this.i18nRender('红太狼'),
dataIndex: 'Path',
key: 'Path'
}
];
this.selectedColumns = this.columns;
},
methods: {
handleMenuClickAll_comm() {
console.log(this.columns);
if (this.checkedColumn.length === this.columns.length) {
this.selectText = '全选';
this.checkedColumn = [];
} else if (this.checkedColumn.length > 0 && this.checkedColumn.length < this.columns.length) {
if (this.selectText === '全选') {
this.checkedColumn = [];
this.columns.forEach(item => {
this.checkedColumn.push(item.key);
});
this.selectText = '全取消';
} else {
this.checkedColumn = [];
this.selectText = '全选';
}
} else {
this.selectText = '全取消';
this.checkedColumn = [];
this.columns.forEach(item => {
this.checkedColumn.push(item.key);
});
}
},
handleMenuClick_comm(e) {
if (this.checkedColumn.length === 0) {
this.$message.info('请至少勾选一项!');
return;
}
this.visible = false;
if (this.checkedColumn.length > 0) {
let selectedColumns = this.columns.map(item => {
if (this.checkedColumn.indexOf(item.key) >= 0) {
item.isShow = '1';
return item;
} else {
return null;
}
});
this.selectedColumns = _.cloneDeep([...selectedColumns.filter(item => item !== null)]);
}
},
colseMenuClick() {
this.visible = false;
},
onDrop(info) {
const dropKey = info.node.eventKey;
const dragKey = info.dragNode.eventKey;
const dropPos = info.node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (data, key, callback) => {
data.forEach((item, index, arr) => {
if (item.key === key) {
return callback(item, index, arr);
}
if (item.children) {
return loop(item.children, key, callback);
}
});
};
const data = [...this.columns];
// Find dragObject
// 只在父级下进行拖拽
let dragObj;
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
let ar;
let i;
loop(data, dropKey, (item, index, arr) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
this.columns = data;
},
onDragEnter(info) {
console.log(info);
}
}
};
</script>
<style lang="less" scoped>
.selectMenuCont {
float: right;
margin-bottom: 41px;
margin-right: 10px;
}
</style>
从代码上看我在官网的基础上进行了部分代码的删减,因为在前端要做到的是checkbox类型的复选和拖拽,又因为只有树有拖拽所以不不允许拖拽到父节点下,只能同级拖拽。
其次是只在点击确定下触发的事件。 !!!!切记data里一定不要漏掉声明