本示例基於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);
效果圖