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);
效果图