Vue 多层级目录拖动排序
本示例基于Vue.Draggable中Nested示例,git地址:https://github.com/SortableJS/Vue.Draggable
需求描述
基于多表头列表的一种后台设置:
1.列字段可以拖进表头目录中(文件与文件夹的关系)
2.可修改表头目录名称
3.可删除表头目录(删除后目录内部的列重排)
效果图如下:

设置完成后在前台列表的展示:

代码
1.nested-main.vue
<template>
<div class="row">
<div class="col-8">
<nested-draggable :tasks="list" />
</div>
<rawDisplayer
class="col-3"
:value="list"
title="List"
/>
</div>
</template>
<script>
import nestedDraggable from './infra/nested';
export default {
name: 'nested-main',
display: 'Nested',
order: 15,
components: {
nestedDraggable,
},
data() {
// 文件夹最后需要加一个{name:"",type:0,emptyHolder:true,tasks:[]}的空对象占位,否则无法拖进去
return {
list: [
{
name: 'task 1 文件夹',
type: 0,
tasks: [
{
name: 'task 2 文件',
type: 1,
tasks: []
},
{
name: '',
type: 0,
emptyHolder: true,
tasks: []
},
],
},
{
name: 'task 3 文件夹',
type: 0,
tasks: [
{
name: 'task 4 文件',
type: 1,
tasks: [],
},
{
name: '',
type: 0,
emptyHolder:true,
tasks: []
},
],
},
{
name: 'task 5 文件',
type: 1,
tasks: []
},
{
name: 'task 6 文件夹',
type: 0,
tasks: [
{
name: 'task 6-1 文件夹',
type: 0,
tasks: [
{
name: '',
type: 0,
emptyHolder:true,
tasks: []
},
],
},
{
name: '',
type: 0,
emptyHolder:true,
tasks: []
},
],
},
{
name: 'task 7 文件夹',
type: 0,
tasks: [
{
name: '',
type: 0,
emptyHolder:true,
tasks: []
},
],
}
],
};
},
};
</script>
<style scoped></style>
2.nested-draggable.vue
<template>
<div v-if="tasks&&tasks.length>0">
<draggable
class="dragArea"
tag="div"
v-bind="dragOptions"
:list="tasks"
:group="{ name: 'g1' }"
>
<template v-for="(el,index) in tasks">
<div
draggable=".item"
class="list-group-item"
:class="{'nested-1':el.type==0,'nested-2':el.type==1}"
v-if="!el.emptyHolder"
:key="index"
>
<p>{{ el.name }}</p>
<nested-draggable :tasks="el.tasks"></nested-draggable>
</div>
</template>
</draggable>
</div>
</template>
<script>
import draggable from '@/vuedraggable';
export default {
name: 'nested-draggable',
components: {
draggable,
},
computed: {
dragOptions() {
return {
group: 'nested',
ghostClass: 'ghost',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
};
},
},
props: {
tasks: {
required: true,
type: Array,
},
},
methods: {
},
};
</script>
<style scoped>
.dragArea {
min-height: 50px;
outline: 1px dashed;
}
.list-group {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
padding-left: 0;
margin-bottom: 0;
}
.list-group-item {
margin-top: 5px;
position: relative;
display: block;
padding: 0.75rem 1.25rem;
margin-bottom: -1px;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.125);
}
.nested-1 {
background-color: #e6e6e6;
}
.nested-2 {
background-color: #cccccc;
}
.nested-3 {
background-color: #b3b3b3;
}
</style>
3.关于取值
每个文件夹最后都有一个冗余的对象{name: '',type: 0,emptyHolder:true,tasks: []}
我们可以通过emptyHolder:true属性来进行过滤。
以下是递归的一种实现方式:
var f = item => { if (item['Children'] && item['Children'].length > 0) { item['Children'] = item['Children'].filter(f); return true; } else if (item.Type == 0 && item.emptyHolder) { return false; } else { return true; } }; const filterNestedProperty = this.nestedProperty.filter(f);
效果图


浙公网安备 33010602011771号