Vue使用el-tree 懒加载进行增删改查功能的实现

关于vue的树形展示 使用到项目:以树的形式异步展现
效果图先放:

找到element-ui的官方文档,el-tree。(地址:https://element.eleme.cn/#/zh-CN/component/tree

项目需求:以懒加载的形式展示,目录根据需求需要有新增 编辑 删除 操作以及操作后的刷新树结构

那我们现在开始吧

一、

懒加载:Tree的懒加载,用一个属性控制:lazy。使用lazy,就要使用load来加载数据进行渲染树
原理:初始化触发load函数先加载初始数据,通过点击某个节点,触发load函数,来加载这个节点下的子节点。
优点:适合数据量比较大的时候,对部分节点刷新也比较友好

二、

自定义节点:节点后添加操作按钮


简单例子官网上就有示例

**

主要讲讲更新节点

**
当对节点进行编辑、删除时,需要更新树,只需更新节点,不必更新全部的树即可。
原理:更新节点,其实更新的是该节点的子节点,不包括本节点。删除该节点的子节点,重新请求数据获取本节点的子节点数据进行重新渲染。

// refreshNode:要刷新的节点;newNodeData:新的子节点数据
refreshNode.splice(0, refreshNode.length);
refreshNode.doCreateChildren(newNodeData);

理解一下:
1>.方法node-click调用函数menuNodeClick,记录点击的节点信息,对节点操作前,必然先点击选中某个节点。此函数监听点击节点事件,只要点击了节点,就触发:

menuNodeClick(data, node, treeNode) {
    this.selectNodeData = data
    this.selectNode = node
}

2>.节点操作后刷新节点即可,通过不同场景可以选择刷新本节点(node)还是刷新本节点的父节点(node.parent):

/**
* 刷新节点数据
* @node [node/Object]: 刷新的节点node,刷新node以下的所有节点
* @type [String]: node的类型,'node'表示node是树的节点信息Node;'data'表示node是树节点信息中的data数据
*/
refreshTreeNode(node, type) {
    let refreshNode;
    // 拿到要更新节点的子节点
    if(type === 'node') {
        refreshNode = node.childNodes
    }else if(type === 'data') {
        let getNode = this.$refs.tree.getNode(node)
        refreshNode = getNode.childNodes
    }
    // 删除原有的子节点
    refreshNode.splice(0, refreshNode.length);
    //重新请求数据,更新节点
    this.requestTreeNode(node)
}

3.选择框checkBox:

如果懒加载中,有选择框,需要将有选择框的数据加载出来,然后通过属性default-checked-keys来勾选,通过default-expanded-keys设置展开的节点。

4.单选:
如果在懒加载中,有单选项,则设置选中即可:

// 设置当前节点选中
this.$refs.tree.setCurrentKey(
    this.selectNodeData[this.nodeKey]
)

不管是单选还是多选,在第一次加载时,后台要给的,不只是选中信息,还需要选中节点所在分支的所有节点信息,赋值给default-expanded-keys以便可使节点所在分支从上到选择项都展开。但往往,后台可能给的,只是选中值的信息,这就要前端自己封装数据,获取需要展开的分支信息。根据数据格式不同,用不同的方法
1)树形单层数据格式:

[
    {...},
    {...},
    {...}
]

这种格式的数据,【点击一层,加载一层】、【点击一层,加载该点击层的多层子节点】两种情况都可以满足。第一种不需要进行数据处理;第二种情况,需要在每条数据中注入一个字段,用来关联父子节点,然后将数据封装处理成el-tree所需要的格式,用一个递归函数整合数据(假设关联字段为parentId,nodeKey为id,树的子节点字段为children,需要加载id为'N'的多层子节点)(注:递归函数会影响性能,谨慎使用)

2).多层数据(假设子节点的属性名是children)

[
    {
        ...,
        children: [
            {
                ...,
                children: [
                    {
                        ...,
                        children: [...],
                    },
                    {
                        ...,
                        children: [...],
                    }
                ]
            },
            {
                ...,
                children: [
                    {
                        ...,
                        children: [...],
                    }
                ]
            }
        ]
    }

]

这种格式的数据,单层、多层都可以满足,不需要做处理。
选中值整合并展开选中值所在的树:多层数据可由后台给出选中节点所在的整个分支的值,赋给default-expanded-keys进行展开。也可以自己做筛选,写一个递归函数,将多层数据循环,找到选中值的节点的分支来设置展开(假设nodeKey为id,树的子节点字段为children,需要展开id为'N'的节点所在的整个分支)

懒加载示例:
HTML控件:

<el-tree
            :data="treeData"
            :props="defaultProps"
            :load="loadNodeTree"
            @node-click="handleNodeClick"
            lazy
            :expand-on-click-node="false"
             :default-expanded-keys="['1']"
            node-key="id"
            :highlight-current="true"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span class="treeLeft">{{ node.label }}</span>
              <span class="treeRight">
                <i
                  v-if="node.level === 1"
                  @click="() => appendNode(node, data)"
                  class="el-icon-plus"
                  style="color: blue"
                ></i>
                <!--增加分组-->
                <!-- 根节点不需要删除和重命名 -->

                <i
                  v-if="data.id !== 0"
                  @click="() => deleteNode(node, data)"
                  class="el-icon-delete"
                  style="color: red"
                ></i>
                <!--删除分组-->

                <i
                  v-if="data.id !== 0"
                  @click="() => editNode(node, data)"
                  class="el-icon-edit"
                  style="color: blue"
                ></i>
                <!--重命名分组-->
              </span>
            </span>
          </el-tree>

vue:
data里面定义变量

 // 树形菜单
      treeData: [], // 树节点
      defaultProps: { // 修改el-tree默认data数组参数
        children: 'children',
        label: 'name',
        id: 'id',
        parentId: 'parentId',
        isLeaf: 'leaf' // 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效
      },

methods:
加载树形菜单部分

 // 加载 树数据
    loadNodeTree(node, resolve) {
      const that = this
      if (node.level === 0) {
        that.loadtreeData(node, resolve)
      } else if (node.level === 1) {
        that.getChildByList(node, resolve)
      }
    },
    // 获取loadtreeData 就是父节点数据,getChildByList就是异步获取子节点数据
    loadtreeData(nodeData, resolve) {
      const dataType = {
        pageIndex: 1,
        pageSize: 100000
      }
      getAlltype(dataType)
        .then(res => {
          const rootChildren = []
          if (res.code === 200) {
            const data = res.data.list
            data.map(item => {
              rootChildren.push({
                name: item.typeName,
                parentId: '',
                id: item.id,
                leaf: false,
                children: []
              })
            })
            //如果resolve有内容就是懒加载走查询 否则走的是修改
            if (resolve) {
              resolve(rootChildren)
            } else {
              nodeData.childNodes = []
              nodeData.doCreateChildren(rootChildren)
            }
          } else {
            resolve([])
          }
        })
    },
    // 获取子节点请求
    getChildByList(nodeData, resolve) {
      var _parentID = nodeData.data.id
      const typeSpec = {
        typeId: _parentID,
        pageIndex: 1,
        pageSize: 100000
      }
      getAlltypeSpec(typeSpec).then(res => {
        const rootChildren = []
        if (res.code === 200) {
          const data = res.data.list
          data.map(item => {
            rootChildren.push({
              name: item.description,
              parentId: item.typeId,
              id: item.id,
              leaf: true,
              children: []
            })
          })
          if (resolve) {
            resolve(rootChildren)
          } else {
            nodeData.childNodes = []
            nodeData.doCreateChildren(rootChildren)
          }
        } else {
          return false
        }
      }).catch(err => {
        console.log(err)
      })
    },
    // 节点点击事件
    handleNodeClick(data, node) {
      this.addnode = node
      this.adddata = data
      if (node.level === 1) {
        this.queryForm.typeId = node.data.id
        this.queryForm.typeSpecId = ''
      } else if (node.level === 2) {
        this.queryForm.typeId = node.data.parentId
        this.queryForm.typeSpecId = node.data.id
      }
      this.query()
    },

节点操作:增加节点 修改节点 删除节点 (操作自己节点要传父节点信息才能找到自己当前节点,操作子节点就传当前节点 结论:父节点操作子节点)

 // 树节点增加 类型规格
    appendNode(node, data) {
      this.addTypesSpec = {
        typeName: node.data.name,
        typeId: node.data.id
      }
      this.createTypesSpecDialog = true
    },
    // 树类型修改
    editNode(node, data) {
      const typeId = node.data.parentId
      // 一级 类型
      if (node.level === 1) {
        this.editTypesDialog = true
        this.editTypes = {
          id: node.data.id,
          typeName: node.data.name
        }
      } else {
        this.editTypesSpecDialog = true
        this.getSelectTypes()
        // this.editTypesSpec = Object.assign({}, node.data)
        this.editTypesSpec = {
          typeId: typeId,
          id: node.data.id,
          description: node.data.name
        }
      }
    },

    // 树类型删除
    deleteNode(node, data) {
      // 一级 类型
      if (node.level === 1) {
        this.$msgbox.confirm('此操作将删除资产类型数据, 是否继续?', '删除提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          typeDel(node.data.id).then(
            resp => {
              this.$message('删除成功')
              this.query()
              this.loadNodeTree(node.parent)
            },
            err => {
              console.log('err', err)
            }
          )
        }).catch(() => {
          this.$message.error('已取消')
        })
      } else {
        this.$msgbox.confirm('此操作将删除资产类型规格数据, 是否继续?', '删除提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          typeSpecDel(node.data.id).then(
            resp => {
              this.loadNodeTree(node.parent)
              this.$message('删除成功')
              this.query()
            },
            err => {
              console.log('err', err)
            }
          )
        }).catch(() => {
          this.$message.error('已取消')
        })
      }
    },

节点触发之后显示弹框 走正常的弹框增加修改删除操作,只不过在提交后台请求返回操作成功之后需要再一次加载树形结构 所以在这里再一次调用加载树形方法,传的node 当触发点击树形的时候可以保存一下,我的是handleNodeClick这个方法 不管点击修改 增加还是删除都保存下点击的node

 this.$message('编辑成功')
              this.loadNodeTree(this.addnode.parent)

1.设置展开和收缩

if (!node.expanded) {
    node.expand();
}else {
    node.collapse();
}

2.获取父节点

node.parent

看得懂的就看吧 代码可以优化 但是最近没啥时间 看不懂的能清楚这个逻辑也行啊 下次见

到此这篇关于Vue使用el-tree 懒加载进行增删改查的文章就介绍到这了,更多相关Vue el-tree 懒加载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue el-tree 默认展开第一个节点的实现代码

    vue 的树形控件 el-tree 可以用来方便地实现树形控件,但是官方文档中,关于控件的默认展开只有默认展开全部或者默认全部关闭,如下所示: 对于指定节点的展开,需要指定其id,从而通过 default-expanded-keys 设置默认展开的节点. 对于后台返回的数据,默认展开其第一层的第一个,其实很简单:对于获取到的后台数据,将其第一层节点添加到数组中,将 default-expanded-keys 绑定数组,从而设置默认展开的节点. 实际应用:默认展开第一层节点中的第一个节点: <te

  • vue elementUI table表格数据 滚动懒加载的实现方法

    在项目中遇到了一个性能问题 vue+elementUI table表格展示数据,当数据很多的时候,不能一页显示完,同时一次请求数据量太大,会增加网页渲染的时间,影响体验, 这个时候常常有两种方法处理, 1.分页,如下 2.如果我不想分页,又想在一页显示全部数据呢?这个时候其实就可以用数据懒加载了 如下一开始表格只显示31行数据 当将滚动条拉到低的时候,就会再加载31条数据,如果剩下的数据不足31,那就加载剩下的 根据项目需求,这需要一页可以看到全部数据,所以我选择了第二中方式 那么第二种方式要怎

  • vue实现表格增删改查效果的实例代码

    整理文档,搜刮出一个vue实现表格增删改查效果的实例代码,稍微整理精简一下做下分享. 实现效果 我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行: list: [ { username: 'aaaaa', email: '123@qq.com', sex: '男', province: '北京市', hobby: ['篮球', '读书', '编程'] }, { username: 'bbbbb', email: 'bbbbbbb@163.com', sex: '女', p

  • 利用vue3+ts实现管理后台(增删改查)

    简单的管理后台基本上就是数据的增删改查.主要就是 列表 + form 表单.每个页面的逻辑基本上都相同.不同的地方就是每个页面需要调用的具体 API 及参数. 以前 vue2 的时候最简单的做法是写出来一个页面的逻辑,然后直接 copy 到各个页面中,修改 API 及参数即可.高级一点的是利用 mixin 函数,将可复用逻辑抽离,每个页面引入 mixin. vue3 之后新增了composition API.本文就是利用composition API,将可复用的逻辑抽离到composition

  • vue实现图片懒加载的方法分析

    本文实例讲述了vue实现图片懒加载的方法.分享给大家供大家参考,具体如下: vue图片懒加载使用 首先第一步,安装插件 vue-lazyload npm install vue-lazyload --save-dev 在man.js中引入插件 import VueLazyLoad from 'vue-lazyload' 使用 Vue.use(VueLazyLoad,{ error:'', //加载失败的图 loading:'' //加载中的默认图 }) 这是一个最简单的配置 官方的详细扩展配置文

  • VUE+Element实现增删改查的示例源码

    前言 &最近因为一些原因,没有更博客,昨天老师布置了一个作业,用vue实现增删改查功能,想想这也不难,就做一下试试吧. 因为自己写的样式没有别人做的好,因此我想用现成的UI框架,一直也没用过Element,就干脆趁机学一下吧. 实验步骤 首先引入一下element的css以及js <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chal

  • Vue使用el-tree 懒加载进行增删改查功能的实现

    关于vue的树形展示 使用到项目:以树的形式异步展现 效果图先放: 找到element-ui的官方文档,el-tree.(地址:https://element.eleme.cn/#/zh-CN/component/tree ) 项目需求:以懒加载的形式展示,目录根据需求需要有新增 编辑 删除 操作以及操作后的刷新树结构 那我们现在开始吧 一. 懒加载:Tree的懒加载,用一个属性控制:lazy.使用lazy,就要使用load来加载数据进行渲染树 原理:初始化触发load函数先加载初始数据,通过点

  • Vue+Mock.js模拟登录和表格的增删改查功能

    前言 关于mockjs,官网描述的是 1.前后端分离 2.不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据. 3.数据类型丰富 4.通过随机数据,模拟各种场景. 5 项目不背锅(等后端给接口的话可能会背锅) 等等优点,最后一条我加的. 第一步先安装mock.js npm install mockjs --save-dev 第二步使用 mock.js import Mock from 'mockjs' 哪里用就在哪里引入.我是在项目src/mock/index.js里面使用moc

  • vue+element tree懒加载更新数据的示例代码

    使用element tree实现懒加载,更新某一节点的数据 1.tree 懒加载 只需要在el-tree标签上面添加lazy,load属性,load的接收是一个函数.这里贴上官网给出的方法 <el-tree :data="treeList" ref="tree" class="vue-tree" lazy :load="loadNode" :highlight-current="true" :node

  • 浅谈vue中使用图片懒加载vue-lazyload插件详细指南

    在vue中使用图片懒加载详细指南,分享给大家.具体如下: 说明 当网络请求比较慢的时候,提前给这张图片添加一个像素比较低的占位图片,不至于堆叠在一块,或显示大片空白,让用户体验更好一点. 使用方式 使用vue的 vue-lazyload 插件 插件地址:https://www.npmjs.com/package/vue-lazyload 案例 demo: 懒加载案例demo Installation 安装方式 npm $ npm i vue-lazyload -D CDN CDN: https:

  • element tree懒加载:load="loadNode"只触发一次的解决方案

    当tree 懒加载获取 信息时,只有在第一次 加载时,触发 :load=“loadNode” ,但是这样明显是不合理的,因为当增删改查,后端数据已经改变,但是咱们的:load=“loadNode” 不会再次触发,导致数据显示问题; <el-tree :props="props" :load="loadNode" lazy @node-click="handleNodeClick"></el-tree> data() { r

  • vue项目实现图片懒加载的简单步骤

    目录 1.安装vue-lazyload插件 2.在main.js中进行引用 3.使用(将图片设置为懒加载) 总结 1.安装vue-lazyload插件 npm install vue-lazyload --save-dev 2.在main.js中进行引用 import VueLazyload from "vue-lazyload"; Vue.use(VueLazyload); //或者自定义配置插件 Vue.use(VueLazyload, { preLoad: 1.3, error:

  • 详解el Cascader懒加载数据回显示例

    正文 数据回显时保证 v-model props options 绑定的数据是正确的. 调用 props.lazyLoad 方法中的 resolve 回掉函数设置数据,示例来自el官网. 好多例子中说需要设置 options, 但是异步获取子节点,设置它是没有用的. <el-cascader :props="props"></el-cascader> <script> let id = 0 export default { data() { retu

  • jQuery+datatables插件实现ajax加载数据与增删改查功能示例

    本文实例讲述了jQuery+datatables插件实现ajax加载数据与增删改查功能.分享给大家供大家参考,具体如下: 这里给大家分享一下我在项目中用datatables实现ajax加载数据与增删改查 注意,需要引入jquery.datatables.layer html代码: <div class="thead"> <input placeholder="请输入搜索内容" id="searchTitle" type=&quo

  • SpringBoot+Vue+Axios+BootStrap实现图书的增删改查功能示例

    目录 一.开发工具 二.项目结构 三.编写项目 四.运行项目 由于是初学Vue.Axios,可能在界面和功能上存在着一些问题,但这些并不妨碍使用.如果有对编程感兴趣的朋友,可以试着做一做.这个由于是第一次做,不太熟练.在后续的过程中会不断的完善. 一.开发工具 IntelliJ IDEA Ultimate 2021.1 apache-maven-3.5.4 MySQL5.7 JDK 1.8.0_281 二.项目结构 三.编写项目 1.创建数据库 SET NAMES utf8mb4; SET FO

  • Vue实现一个图片懒加载插件

    前言 图片懒加载是一个很常用的功能,特别是一些电商平台,这对性能优化至关重要.今天就用vue来实现一个图片懒加载的插件. 这篇博客采用"三步走"战略--Vue.use().Vue.direction.Vue图片懒加载插件实现,逐步实现一个Vue的图片懒加载插件. Vue.use() 就像开发jQuery插件要用$.fn.extent()一样,开发Vue插件我们要用Vue.use().其实就是官方内部实现的一个方法,供广大开发者灵活开发属于自己的插件.只需要按照约定好的规则开发就行. 用

随机推荐