ElementUI el-tree树形实现点击按钮tree节点上下移动

图标

<div class="treeBox"  v-loading="treeLoading">
    <el-tree
        class="departmentTree"
        :data="treeData"
        node-key="id"
        ref="tree"
        highlight-current
        default-expand-all
        :current-node-key="selectedItemId"
        :props="{children: 'children', label: 'label'}"
        @node-click="nodeClick"
    >
        <div class="custom-tree-node" slot-scope="{ node, data }">
            <div class="iconFile"></div>
            <template v-if="data.isEditing">
                <el-input class="nameInput" v-model="data.label" size="mini" placeholder="输入名称">
                    <img slot="suffix" class="iconSure" src="@/assets/images/icon_sure.png" alt="" @click.stop="sureCreate(node, data)">
                    <img slot="suffix" class="iconClose" src="@/assets/images/icon_close.png" alt="" @click.stop="cancelCreate(node, data)">
                </el-input>
            </template>
            <template v-else>
                <span class="fileName">{{ data.label }}</span>
                <!-- 三个点图片 -->
                <el-dropdown 
                    v-if="selectedItemId == data.id" 
                    trigger="click" 
                    @command="dropDownClick($event, data, node)"
                >
                    <div class="el-dropdown-link">
                        <div class="iconMore"></div>
                    </div>
                    <el-dropdown-menu slot="dropdown" class="simu-dropdown">
                        <el-dropdown-item
                            v-for="item in nodeHandles"
                            :key="item"
                            :command="item"
                        >
                            {{item}}
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
                <div v-else class="iconMore"></div>
            </template>
        </div>
    </el-tree>
</div>
<script>
    export default {
        data(){
            return{
                treeLoading: false,
                // 列表
                treeData: [{
                    id: '1',
                    label: '一级 1',
                    isEditing: false,
                    children: [{
                        id: '2',
                        label: '二级 1-1',
                        isEditing: false,
                        children: [{
                            id: '11',
                            label: '三级 1-1-1',
                            isEditing: false,
                        }]
                    }]
                    }, {
                        id: '3',
                        label: '一级 2',
                        isEditing: false,
                        children: [{
                            id: '4',
                            label: '二级 2-1',
                            isEditing: false,
                            children: [{
                                id: '5',
                                label: '三级 2-1-1',
                                isEditing: false,
                            }]
                        }, {
                            id: '6',
                            label: '二级 2-2',
                            isEditing: false,
                            children: [{
                                id: '7',
                                label: '三级 2-2-1',
                                isEditing: false,
                            }]
                        }]
                    }, {
                        id: '8',
                        label: '一级 3',
                        isEditing: false,
                        children: [{
                            id: '9',
                            label: '二级 3-1',
                            isEditing: false,
                            children: [{
                                id: '10',
                                label: '三级 3-1-1',
                                isEditing: false,
                            }]
                        }, {
                            id: '11',
                            label: '二级 3-2',
                            isEditing: false,
                            children: [{
                                id: '12',
                                label: '三级 3-2-1',
                                isEditing: false,
                            }]
                        }
                    ]
                }],
                selectedItemId: '', // 选中的id
                nodeHandles: ['添加子部门','修改名称','删除','上移','下移'],
            }
        },
        mounted(){

        },
        methods:{
            // el-tree的节点点击事件
            nodeClick (event) {
                this.selectedItemId = event.id
                this.$nextTick(() => {
                    this.$refs.tree.setCurrentKey(this.selectedItemId)
                })
            },
            // 树节点操作
            dropDownClick(val, data, node){
                this.treeType = val
                if(val == '添加子部门'){
                    let addFind = (arr, data) => {
                        arr.forEach(item => {
                            if(item.id == data.id){
                                item.children.push({
                                    id: item.id + 's',
                                    isEditing: true,
                                    label: '',
                                    parentId: item.id
                                })
                            }else if(item.children && item.children.length != 0){
                                addFind(item.children, data);
                            }
                        })
                    }
                    addFind(this.treeData, data)
                }else if(val == '修改名称'){
                    this.findTree(this.treeData, data.id);
                }else if(val == '删除'){
                    this.$message.success('删除成功')
                       
                }else if(val == '上移'){
                    let fatherChildren = node.parent.data.children || []
                    let selfIndex = fatherChildren.findIndex(a => a.id == data.id)
                    if (selfIndex) {
                        let reqData = {
                            id: data.id, 
                            changeId: fatherChildren[selfIndex - 1].id
                        }
                        console.log('上移', reqData)
                        
                    } else {
                        this.$message.warning('不能再上移了')
                    }
                }else if(val == '下移'){
                    let fatherChildren = node.parent.data.children || []
                    let selfIndex = fatherChildren.findIndex(a => a.id == data.id)
                    if (selfIndex == fatherChildren.length - 1) {
                        this.$message.warning('不能再下移了')
                    } else {
                        let downData = {
                            id: data.id, 
                            changeId: fatherChildren[selfIndex + 1].id
                        }
                        console.log('下移', downData)
                        
                    }
                }
            },
            // 根据id 修改isEditing值
            findTree(arr, id){
                arr.forEach((item) => { 
                    if(item.id == id){        
                        item.isEditing = !item.isEditing;
                        return item;
                    }else if(item.children && item.children.length != 0){
                        this.findTree(item.children, id);                        
                    }                   
                })
            },
            // 确认添加、修改子级
            sureCreate(node, data){
                if(this.treeType == '添加子部门'){
                    this.findTree(this.treeData, data.id)
                    this.$message.success('添加成功')

                }else if(this.treeType == '修改名称'){
                    this.findTree(this.treeData, data.id)
                    this.$message.success('修改成功')
                    
                }
            },
            // 取消添加、修改子级
            cancelCreate(node, data){
                if(this.treeType == '添加子部门'){
                    let find = (arr, id) => {
                        arr.forEach((item, index) => { 
                            if(item.id == id){   
                                console.log(item.id ) 
                                console.log(id )  
                                arr.splice(index, 1)
                            }else if(item.children && item.children.length != 0){
                                find(item.children, id);                        
                            }                   
                        })
                    }
                    find(this.treeData, data.id)
                }else if(this.treeType == '修改名称'){
                    this.findTree(this.treeData, data.id)
                }
            },
        }
    }
</script>
<style lang="scss">
.treeBox{
    .departmentTree {
        .el-tree-node__content {
            height: 32px;
            &:hover{
                background: #EBEDF0;
            }
        }
        .el-tree-node.is-current {
            &>.el-tree-node__content {
                background-color: #02C2B0;
                .iconFile {
                    background-image: url('./assets/images/organization-default.png');
                }
                .iconMore {
                    opacity: 1 !important;
                    background-image: url('./assets/images/icon_more_active.png');
                }
                .fileName,.el-tree-node__expand-icon {
                    color: #fff;
                }
                .el-tree-node__expand-icon.is-leaf{
                    color: transparent;
                    cursor: default;
                }
            }
        }
        .custom-tree-node {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: space-between;
            .iconFile {
                width: 14px;
                height: 14px;
                margin-right: 6px;
                background-image: url('./assets/images/organization.png');
                background-repeat: no-repeat;
                background-size: cover;
            }
            .iconSure {
                margin: 0 6px;
            }
            .iconClose {
                margin-right: 11px;
            }
            .nameInput {
                flex: 1;
                background: #fff;
                input {
                    width: calc(100% - 56px);
                    height: 22px;
                    padding: 0 4px;
                    background: #EBEBEB;
                    border-radius: 0;
                    border: none;
                } 
                .el-input__suffix {
                    right: 0;
                }
                .iconClose{
                    margin-right: 0;
                }
            }
            .fileName {
                flex: 1;
                line-height: 22px;
                font-size: 14px;
                color: #303133;
            }
            .iconMore {
                opacity: 0;
                width: 2px;
                height: 10px;
                margin: 6px 12px;
                background-image: url('./assets/images/icon_more.png');
                background-repeat: no-repeat;
                background-size: cover;
            }
        }
    }
    .el-dropdown-menu__item:hover {
        background-color: #7BDFD6!important;
        color: #fff!important;
    }
}
.simu-dropdown{
    li:hover{
        color: #fff!important;
        background: #7BDFD6!important;
    }
}

</style>