Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载

Element-ui树形控件el-tree增删改和局部刷新及懒加载

需求: vue-cli项目树形控件:一级节点为本地节点,默认展开一级节点,增删改后局部刷新数据。
el-tree树状图
增加节点,点击确定后局部刷新,渲染新数据。
在这里插入图片描述

源码

element组件样式

			<el-tree 
                class="treeitems"
                :data="data"
                node-key="id"
                :props="defaultProps" 
                :load="loadNode"
                lazy
                :default-expanded-keys="[0]"
                @node-click="handleNodeClick"
                draggable
                :allow-drop="allowDrop"
                :allow-drag="allowDrag"
                 @node-drop="handleDrop"
                ref="tree"
            >
            <span class="custom-tree-node" slot-scope="{ node, data }">
                <span>{{ node.label }}</span>
                <span>
                    <i @click="() => append(node,data)" class="el-icon-plus"></i><!--增加分组-->
                    <!-- 根节点不需要删除和重命名 -->
                    <i v-if="data.id !== 0" @click="() => deletes(node,data)" class="el-icon-delete"></i><!--删除分组-->
                    <i v-if="data.id !== 0" @click="() => rename(node,data)" class="el-icon-edit"></i><!--重命名分组-->
                </span>
            </span>
         </el-tree>

data数据

data() {
      return {
        filterText: '',
        data: [{
            id:0,
            label: '中国',
            
        }],
        children: [{
                id:1,
                label: '北京',
                children: [{
                    id:11,
                    label: '通州'
                }]
            },
            {   
                id:2,
                label: '上海',
                leaf: true,
            },
            {   
                id:3,
                label: '山西',
                children:[{
                    id: 13,
                    label: '太原'
                },{
                    id: 14,
                    label: '阳泉'
                }]
            },{
                id:4,
                label: '黑龙江',
                children: [{
                    id:12,
                    label: '哈尔滨'
                }]
            }],
        defaultProps: {
          children: 'children',
          label: 'label',
          isLeaf: 'leaf'
        }
      };

点击增加节点弹出弹窗
这里也用的是element的弹窗,直接在methods里写:

		//点重命名事件
		append(node,data) {
           console.log(node,data,'增加')
           this.$prompt('节点名字', '增加节点', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                inputPattern: /^[\u4e00-\u9fa5]{0,}$/,//匹配全中文
                inputErrorMessage: '请输入中文'//不符合正则匹配的提示语句
                }).then(({ value }) => {
                    //可以在这里发请求,http是我模拟的一个虚假的封装好的axios请求,()可写请求参数
                    http().then((data)=>{
                        this.$message({
                            type: 'success',
                            message: '修改成功'
                        });  
                        //请求成功需局部刷新该节点,调用方法,把节点信息node传入
                        this.partialRefresh(node)
                    })
                    //请求失败
                    .catch(()=>{
                        this.$message({
                            type: 'info',
                            message: '修改失败'
                        });  
                    })
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '取消修改'
                    });       
            });
        },
        //实现局部刷新,在点击弹窗处调用的
        partialRefreshpartialRefresh(node){
            //设置loaded为false;模拟一次节点展开事件,加载重命名后的新数据;
            node.loaded = false;
            node.expand(); 
            //新建子节点是刷新一次本节点的展开请求,而重命名和删除则需要刷新父级节点的的展开事件,
            //可以设置node.parent.loaded = false;node.parent.expand();
        },

懒加载
在这里插入图片描述
该处可直接设置有无节点,如果后端返回有无节点的表示就可用,若无可舍弃。(data中写,我在本地模拟数据上海字段中加了leaf: true,上海节点就默认没有节点了)

		//懒加载
        loadNode(node, resolve){
            if (node.level === 0) {
                //本地的数据,一个承载中国字样的数组;
                return resolve(this.data);
            }
            else if(node.level === 1){
                //现在为模拟数据;
                //有真实数据,在resolve中放置请求回来的数据即可。
                //else同样也是。我这里是区分了两种请求方式。
                return resolve(this.children)
            }
            else{
                return resolve([])
            }
        },

拖拽节点

		 //拖拽==>拖拽时判定目标节点能否被放置
        allowDrop(draggingNode, dropNode, type){
            //参数:被拖拽节点,要拖拽到的位置
            //因为根目录是我本地写死的,不能有同级,所以我设置凡是拖拽到的level===1都存放到根节点的下面;
            if(dropNode.level===1){
                return type == 'inner';
            }
            else {
                return true;
            }
        },
        //拖拽==>判断节点能否被拖拽
        allowDrag(draggingNode){
	        //第一级节点不允许拖拽
            return draggingNode.level !== 1;
        },

需求改了,同级节点拖拽,拖拽完成后将排序结果返回后端:

//拖拽==>拖拽时判定目标节点能否被放置
        //后更改为只能同级拖拽
        allowDrop(draggingNode, dropNode, type) {
            if (draggingNode.level === dropNode.level) {
                if (draggingNode.data.parentId === dropNode.data.parentId) {
                    return type === 'prev' || type === 'next'
                }
            } else {
                // 不同级不允许拖拽
                return false
            }
        },
        //拖拽==>判断节点能否被拖拽
        allowDrag(draggingNode) {
            return draggingNode.level !== 1;
        },
        //拖拽成功完成时触发的事件,在这里可以将节点拖拽后的顺序返给后端
        handleDrop(node,data,type,event){
            let arr=[];
            //data为拖拽后节点信息,找到它的父级,在从父级找子集
            let child = data.parent.childNodes;
            for(var key in child){
                arr.push({id:child[key].data.id})
            }
            //转为JSON字符串发请求带走信息
            idSort(JSON.stringify(arr))

        }
发布了15 篇原创文章 · 获赞 15 · 访问量 1383

猜你喜欢

转载自blog.csdn.net/qq_45074127/article/details/103106894
今日推荐