如何通过El-Table 和Sortable实现拖拽1

文章描述了一个使用Vue.js和Sortable.js实现的可拖动的树形表格组件,用户可以添加、移动二级节点,并处理不同层级间的拖拽事件,保持树形结构的更新。
摘要由CSDN通过智能技术生成
<template>
    <div class="draggable" style="padding: 20px">
        <el-table ref="sortableTable" row-key="id" :data="treeData" :key="tableKey" style="width: 100%">
            <el-table-column prop="展开" width="40"></el-table-column>
            <el-table-column prop="添加二级" width="60">
                <template slot-scope="scope">
                    <span style="cursor: pointer; color: #100db1" @click="addItem(scope['row'])"
                        v-if="scope['row']['level'] === 1">{{ '+ 二级' }}</span>
                </template>
            </el-table-column>
            <el-table-column prop="拖拽" width="40">
                <template slot-scope="scope">
                    <i class="el-icon-setting draggableIcon"></i>
                </template>
            </el-table-column>
            <el-table-column prop="name"> </el-table-column>
            <el-table-column>
                <template slot-scope="scope">
                    <div class="hoverStyle">
                        <img src="../../assets/imgs/公共日期@2x.png" alt="">
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>
<script>
import Sortable from 'sortablejs';

export default {
    mounted() {
        this.rowDrop();

    },
    data() {
        return {
            tableKey: 0,
            mouseOver: {},
            activeRows: [],
            treeData: [
                {
                    id: 1,
                    level: 1,
                    name: '李一',
                    gender: '男',
                    age: 30,
                    job: '会计',
                    isOriginalFather: true,
                    children: [
                        {
                            id: 31,
                            level: 2,
                            name: '李一1',
                            gender: '2016-05-01',
                            age: '王小虎',
                            job: '上海市普陀区金沙江路 1519 弄'
                        },
                        {
                            id: 32,
                            name: '李一2',
                            level: 2,
                            gender: '2016-05-01',
                            age: '王小虎',
                            job: '上海市普陀区金沙江路 1519 弄'
                        }
                    ]
                },
                {
                    level: 1,
                    id: 2,
                    name: '王二',
                    gender: '未知',
                    age: 18,
                    job: '无业游民',
                    isOriginalFather: true,
                    children: []
                },
                {
                    id: 3,
                    name: '张三',
                    gender: '男',
                    age: 50,
                    job: '老板',
                    level: 1,
                    isOriginalFather: true,
                    children: [
                        {
                            id: 321,
                            level: 2,
                            name: '张三1',
                            gender: '2016-05-01',
                            age: '王小虎',
                            job: '上海市普陀区金沙江路 1519 弄'
                        },
                        {
                            id: 322,
                            level: 2,
                            name: '张三2',
                            gender: '2016-05-01',
                            age: '王小虎',
                            job: '上海市普陀区金沙江路 1519 弄',
                            children: [
                                {
                                    id: 3221,
                                    level: 3,
                                    name: '张三2222-1',
                                    gender: '2016-05-01',
                                    age: '王小虎',
                                    job: '上海市普陀区金沙江路 1519 弄'
                                },
                                {
                                    id: 3222,
                                    level: 3,
                                    name: '张三2222-2',
                                    gender: '2016-05-01',
                                    age: '王小虎',
                                    job: '上海市普陀区金沙江路 1519 弄',
                                    children: [
                                        {
                                            id: 3222222,
                                            level: 4,
                                            name: '张三2222-2--22-2-2-2',
                                            gender: '2016-05-01',
                                            age: '王小虎',
                                            job: '上海市普陀区金沙江路 1519 弄'
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ],
            tableConfig: {
                tableItems: [
                    {
                        label: '姓名',
                        prop: 'name'
                    },
                    {
                        label: '性别',
                        prop: 'gender'
                    },
                    {
                        label: '年龄',
                        prop: 'age'
                    },
                    {
                        label: '工作',
                        prop: 'job'
                    }
                ]
            }
        };
    },
    methods: {
        setMouseOver(index, isHovered) {
            this.$set(this.mouseOver, index, isHovered);
        },
        getUuiD(randomLength) {
            return Number(Math.random().toString().substr(2, randomLength) + Date.now()).toString(36);
        },
        // 添加二级
        addItem(r) {
            let data = {
                id: this.getUuiD(),
                name: '李一11111111',
                gender: '2016-05-01',
                age: '王小虎',
                job: '上海市普陀区金沙江路 1519 弄'
            };
            let idx = this.treeData.findIndex(e => e.id === r.id);
            if (idx > -1) {
                let item = this.treeData[idx];
                if (item.hasOwnProperty('children')) {
                    item.children.push(data);
                } else {
                    item['children'] = [{ ...data }];
                }
            }
            this.treeData = [...this.treeData];
        },
        // 行拖拽
        rowDrop() {
            // 获取表格节点
            // this.tableSortDestroy()
            this.$nextTick(() => {
                const el = this.$refs.sortableTable.$el.querySelector('.el-table__body-wrapper tbody');
                if (!el) {
                    return;
                }
                const _this = this;
                // 插件调用函数
                Sortable.create(el, {
                    animation: 300,
                    handle: '.draggableIcon',
                    onMove({ dragged, related }) {
                        _this.$set(_this, 'activeRows', _this.treeToTile(_this.treeData)); // 把树形的结构转为列表再进行拖拽
                    },
                    onEnd({ oldIndex, newIndex }) {
                        const oldRow = _this.activeRows[oldIndex]; // 移动的那个元素
                        const newRow = _this.activeRows[newIndex]; // 新的元素
                        console.log(oldRow, newRow, 'newRow');

                        if (oldIndex !== newIndex && oldRow.id !== newRow.id) {
                            const modelProperty = _this.activeRows[oldIndex];
                            const changeIndex = newIndex - oldIndex;
                            const index = _this.activeRows.indexOf(modelProperty);
                            if (oldRow.level === newRow.level && oldRow.level === 1) {
                                // 一级之间的拖拽
                                if (index < 0) {
                                    console.log('index < 0');
                                    return;
                                }
                                console.log('111111111');
                                _this.activeRows.splice(index, 1);
                                _this.activeRows.splice(index + changeIndex, 0, modelProperty);
                                _this.sortMenuData('1-1');
                            } else if (oldRow.level === newRow.level && oldRow.level === 2) {
                                // 二级之间的拖拽
                                // _this.activeRows.splice(index, 1)
                                console.log('22222222');
                                let res = [];
                                _this.treeData.forEach(t => {
                                    if (t.hasOwnProperty('children')) {
                                        // 在原来的一级下删除二级
                                        let oldChildIndex = t.children.findIndex(c => c.id === oldRow.id);
                                        if (oldChildIndex > -1) {
                                            t.children.splice(oldChildIndex, 1);
                                        }
                                        // 在新的一级下添加二级
                                        let newChildIndex = t.children.findIndex(c => c.id === newRow.id);
                                        console.log(newChildIndex, 'newChildIndex');
                                        if (newChildIndex > -1) {
                                            t.children = [...t.children.slice(0, newChildIndex), oldRow, ...t.children.slice(newChildIndex)];
                                        }
                                        console.log(t.children, 't.children');
                                    }
                                    res.push(t);
                                    _this.treeData = res;
                                });
                                _this.tableKey = Math.random();
                                _this.rowDrop();
                            } else if (oldRow.level === 2 && newRow.level === 1) {
                                console.log('33333333333');
                                // 二级移动到一级
                                // console.log('2-1', oldRow, newRow)
                                if (newRow.isOriginalFather && (!newRow.children || (newRow.children && newRow.children.length < 1))) {
                                    let res = [];
                                    _this.treeData.forEach(t => {
                                        if (t.children && t.children.length > 0) {
                                            // 在原来的一级下删除二级
                                            let oldChildIndex = t.children.findIndex(c => c.id === oldRow.id);
                                            if (oldChildIndex > -1) {
                                                t.children.splice(oldChildIndex, 1);
                                            }
                                        } else {
                                            if (t.id == newRow.id) {
                                                t.children.push(oldRow);
                                            }
                                        }
                                        res.push(t);
                                        _this.treeData = res;
                                        console.log(_this, 'res最终');
                                        // 将提升为一级的二级放到相应位置
                                    });
                                    _this.tableKey = Math.random();
                                    _this.rowDrop();
                                } else {
                                    let res = [];
                                    _this.treeData.forEach(t => {
                                        if (t.hasOwnProperty('children')) {
                                            // 在原来的一级下删除二级
                                            let oldChildIndex = t.children.findIndex(c => c.id === oldRow.id);
                                            if (oldChildIndex > -1) {
                                                t.children.splice(oldChildIndex, 1);
                                            }
                                        }
                                        // 将提升为一级的二级放到相应位置
                                        let item = { ...oldRow, level: 1 };
                                        if (t.id === newRow.id) {
                                            res.push(t, item);
                                        } else {
                                            res.push(t);
                                        }
                                        _this.treeData = res;
                                    });
                                    _this.tableKey = Math.random();
                                    _this.rowDrop();
                                }
                            } else if (oldRow.level === 1 && newRow.level === 2) {
                                console.log('4444444444444');
                                // 一级移动到二级sww
                                console.log('1-2', oldRow, newRow);
                                var flag = oldRow?.children?.some(item => {
                                    return item.id == newRow.id;
                                });
                                // console.log(flag,'flag');
                                if (!flag) {
                                    let res = [];
                                    let item = [{ ...oldRow, level: 2 }];
                                    item[0]?.children?.forEach(c => {
                                        c.level = 3;
                                    });
                                    console.log(item, 'item0000');
                                    if (oldRow.hasOwnProperty('children')) {
                                        //
                                    }
                                    _this.treeData.forEach(t => {
                                        // 将降为二级的目标以及他的children放到相应的位置
                                        if (t.hasOwnProperty('children')) {
                                            let newChildIndex = t.children.findIndex(c => c.id === newRow.id);
                                            if (newChildIndex > -1) {
                                                t.children = [...t.children.slice(0, newChildIndex), ...item, ...t.children.slice(newChildIndex)];
                                            }
                                        }
                                        if (t.id !== oldRow.id) {
                                            res.push(t);
                                        }
                                    });
                                    console.log(res, 'RES');
                                    _this.treeData = res;
                                    _this.tableKey = Math.random();
                                    _this.rowDrop();
                                } else {
                                    _this.treeData = _this.treeData;
                                    _this.tableKey = Math.random();
                                    _this.rowDrop();
                                }
                            } else if (newRow.level === 3) {
                                _this.treeData = _this.treeData;
                                _this.tableKey = Math.random();
                                _this.rowDrop();
                            }
                        }
                    }
                });
            });
        },
        sortMenuData(type) {
            if (type === '1-1') {
                let res = [];
                this.activeRows.forEach(r => {
                    if (r.level === 1) {
                        let itemIdx = this.treeData.findIndex(t => t.id === r.id);
                        if (itemIdx > -1) {
                            res.push({ ...this.treeData[itemIdx] });
                        }
                    }
                });
                this.treeData = res;
            }
            this.tableKey = Math.random(); //狠狠的刷新dom
            this.rowDrop(); // 再把拖拽的功能塞入
        },

        treeToTile(treeData, childKey = 'children') {
            // 将树数据转化为平铺数据
            const arr = [];
            const expanded = data => {
                if (data && data.length > 0) {
                    data.filter(d => d).forEach(e => {
                        arr.push(e);
                        expanded(e[childKey] || []);
                    });
                }
            };
            expanded(treeData);
            // console.log('treeToTile', arr)
            return arr;
        }
    },
    mounted() {
        this.$nextTick(() => {
            const items = document.getElementsByClassName('hoverStyle')
            console.log(items,'items');
            const temp = Array.from(items)
            temp.forEach(item => {
                item.addEventListener("mouseover", () => {
                    item.classList.add("easeOutAnimate")
                    setTimeout(() => {
                        item.classList.remove("easeOutAnimate")
                    }, 1000)
                })
            });
        });
    },
};
</script>
<style  >
.hoverStyle img{
    opacity: 0;
}
.hoverStyle:hover img {
    opacity: 1 !important;

}

.easeOutAnimate img {
    animation: easeOutAnimate 1s linear;

}

@keyframes easeOutAnimate {
    0% {
        opacity: 1;

    }

    50% {
        opacity: 1;

    }

    100% {

        opacity: 0;
    }

}
</style>

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值