0


Vue+element ui 可编辑树结构

程序员不易,且干且珍惜!

后管项目中,树形图是我们经常用到的一个组件,很多还要求用户可以编辑,增删改查子级。原来一直都是着急忙慌的写上该功能,现在终于有时间整理一下了。

其实,百度上有很多该功能的实现方法,提供给我们开发过程中借鉴,我也尝试过不同的写法,有的效果不佳,有的已经不能用了,本篇文章,是我总结后的自认为比较好用的,我以后遇到此类的需求就可以直接用,在这里,也算是记录一下:

1,实现效果和逻辑

效果:树结构未操作时,所有层级展开,操作按钮隐藏;鼠标移入某层级,该层级显示要求的操作按钮,比如:最后一层级不可添加,其他层级可以增删改。

逻辑:实现树结构可以编辑主要思想就是 - 树结构开启可自定义模式,操作某一层级的时候显示不同的内容(其实也就是不同的操作按钮和输入框),在我们操作结束时,将更改数据存入后端,完成增删改功能,树结构刷新。

2,效果图

未编辑状态 编辑状态:

** 3,实现代码**

<template>
<div class="type-tree">
/
*
*typeData: 树结构数据
*defaultProps:树结构层级配置项
*default-expand-all:默认展开所有层级
*:expand-on-click-node="false":关闭层级默认点击方法(点击收缩展开层级)
*@node-click="handleNodeClick":自定义层级点击方法
*slot-scope="{ node, data }":开启层级内容自定模式
*@mouseenter="mouseenter(data)":鼠标移入某层级方法:改变数据的del变量值,控制操作图标显示
*@mouseleave="mouseleave(data)":鼠标移入某层级方法:改变数据的del变量值,控制操作图标隐藏
*
/
    <el-tree 
    :data="typeData" 
    :props="defaultProps" 
    node-key="id"
    default-expand-all
    :expand-on-click-node="false"
    @node-click="handleNodeClick">
        <div slot-scope="{ node, data }" @mouseenter="mouseenter(data)" @mouseleave="mouseleave(data)" style="width: 100%;">
            <div>
                <!-- 不可编辑情况 -->
                <span v-if="data.id != operationVis" class="custom-tree-node">
                    <span style="width: 50%;display: inline-block;">{{ node.label }} <el-button type="text" icon="el-icon-plus" v-show="node.level === 1" @click="() => append(node, data)"></el-button></span>
                    <span>
                        <!-- 编辑 -->
                        <el-button
                            type="text"
                            size="mini"
                            icon="el-icon-edit"
                            style="color: #53D06B;padding: 3px;"
                            v-show="node.level !== 1 && data.del"
                            @click="() => edit(node, data)">
                        </el-button>
                        <!-- 删除 -->
                        <el-button
                            type="text"
                            size="mini"
                            icon="el-icon-delete"
                            style="color:#FD7474;padding: 3px;"
                            v-show="node.level !== 1 && data.del"
                            @click="() => remove(node, data)">
                        </el-button>
                        <!-- 添加 -->
                        <el-button
                            type="text"
                            size="mini"
                            icon="el-icon-plus"
                            style="color:#39A1FF;padding: 3px;"
                            v-show="(node.level === 2 || node.level === 3) && data.del"
                            @click="() => append(node, data)">
                        </el-button>
                    </span>
                </span>
                <!-- 可编辑情况 -->
                <span v-else class="custom-tree-node">
                    <input
                        style="width: 50%"
                        size="mini"
                        ref="inputVal"
                        :value="data.name"
                        placeholder="请输入分类名"
                        @change="nameChange(data,$event)"
                    />
                    <span>
                        <!-- 编辑确认 -->
                        <el-button
                            type="text"
                            size="mini"
                            icon="el-icon-circle-check"
                            style="color: #53D06B;padding: 3px;"
                            @click="() => checkOK(node, data)">
                        </el-button>
                        <!-- 编辑取消 -->
                        <el-button
                            type="text"
                            size="mini"
                            icon="el-icon-circle-close"
                            style="padding: 3px;"
                            @click="() => checkCancel(node, data)">
                        </el-button>
                    </span>
                </span>
            </div>
        </div>
    </el-tree>
</div>
</template>

<script>
import { getBigKindsTree, saveBigKinds, deleteBigKinds } from '@/api/equipment/equipmentType.js';
export default {
    data(){
        return {
            defaultProps: {
                children: 'subregion',
                label: 'name'
            },
            typeData: [{
                id: '0',
                name: '全部设备',
                subregion: []
            }],
            // 编辑选中的节点
            operationVis: '',
        }
    },
    created(){
        this.getTreeData()
    },
    mounted(){},
    methods:{
        handleNodeClick(data){
            this.$emit('nodeClickData',data)
        },
        mouseenter(data){
            this.$set(data, 'del', true)
        },
        mouseleave(data){
            this.$set(data, 'del', false)
        },
        // tree 获取设备大类数据
        getTreeData() {
            getBigKindsTree()
            .then(res => {
                if(res.data && res.data.code === 0){
                    this.typeData[0].subregion = res.data.data
                }else {
                    this.$message.error('设备分类数据获取失败')
                }
            })
            .catch((err) => {
                this.$message.error(err.message)
            })
        },
        // 树结构编辑方法:将操作的层级ID赋值给operationVis,显示编辑状态下的HTML内容
        edit(node, data){
            this.operationVis = data.id
        },
        // 树结构删除方法:删除选中层级
        remove(node, data){
            let deleteParams = []
            deleteParams.push(data.id)
            deleteBigKinds(deleteParams)
            .then(res => {
                if(res.data && res.data.code === 0){
                    this.$message({
                        message: '删除成功',
                        type: 'success',
                    })
                }else{
                    this.$message.error(res.data.msg || '操作失败')
                }
            })
            .catch((err) => {
                this.$message.error(err.msg)
            }).finally(() => {
                this.getTreeData()
            })
        },
        // 树结构新增方法:在该增加下新增一个子层级,新增的层级在第一个
        append(node, data){
            let num = new Date().getTime()
            let newChild = { id: '' + num, name: '', parentId: data.id, editFlag: '1', subregion: [] }
            if (!data.subregion) {
                this.$set(data, 'subregion', []);
            }
            data.subregion.unshift(newChild);
            this.operationVis = newChild.id
        },
        // tree 新增/编辑确定方法:将新增的层级信息传入后端
        checkOK(node, data){
            // 分类名不填写时,不能正常添加和编辑分类
            if(data && data.editFlag == '1' && !data.label) {
                this.$message.error('操作失败, 分类名称不能为空')
                this.checkCancel()
                return false
            }
            if(data && data.editFlag == '1'){
                let appendParams = {
                    parentId: data.parentId,
                    name: data.label,
                    subregion: []
                }
                saveBigKinds(appendParams)
                .then(res => {
                    if(res.data && res.data.code === 0){
                        this.$message({
                            message: '新增操作成功',
                            type: 'success',
                        })
                    }else{
                        this.$message.error(data.msg || '操作失败')
                    }
                })
                .catch((err) => {
                    this.$message.error(err.message)
                }).finally(() => {
                    this.getTreeData()
                })
            }else{
                let editParams = {
                    id: data.id,
                    parentId: data.parentId,
                    name: data.label,
                }
                saveBigKinds(editParams)
                .then(res => {
                    if(res.data && res.data.code === 0){
                        this.$message({
                            message: '修改操作成功',
                            type: 'success',
                        })
                    }else{
                        this.$message.error(data.msg || '操作失败')
                    }
                })
                .catch((err) => {
                    this.$message.error(err.message)
                }).finally(() => {
                    this.getTreeData()
                })
            }
            this.operationVis = ""
        },
        // tree 编辑取消
        checkCancel(){
            this.operationVis = ""
            this.getTreeData()
        },
        // 树结构编辑状态下,输入框内容写入该层级的数据中
        nameChange(data,e){
            data.label = e.target.value;
        }
    }
}
</script>
    
<style lang="scss" scoped>
.custom-tree-node{
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
}
</style>

该功能就记录到这里,有需要的小伙伴可以直接拿去使用,一般情况下不会有问题,嘎嘎好用!

拜了个拜,迪迦。。。


本文转载自: https://blog.csdn.net/weixin_39166851/article/details/130760644
版权归原作者 清狂无益 所有, 如有侵权,请联系我们删除。

“Vue+element ui 可编辑树结构”的评论:

还没有评论