Vue 多層級目錄拖動排序


本示例基於Vue.Draggable中Nested示例,git地址:https://github.com/SortableJS/Vue.Draggable

需求描述

基於多表頭列表的一種后台設置:

1.列字段可以拖進表頭目錄中(文件與文件夾的關系)

2.可修改表頭目錄名稱

3.可刪除表頭目錄(刪除后目錄內部的列重排)

效果圖如下:

 

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

image.png

代碼

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);

 

效果圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM