本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Vue使用el-tree 懒加载进行增删改查功能的实现
kenrry1992 · 263浏览 · 发布于2021-08-19 +关注

这篇文章主要介绍了Vue使用el-tree 懒加载进行增删改查,以懒加载的形式展示,目录根据需求需要有新增 编辑 删除 操作以及操作后的刷新树结构,具体实现代码跟随小编一起看看吧

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

树形结构展示图

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

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

那我们现在开始吧

一、

在这里插入图片描述

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

二、

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

简单例子官网上就有示例

**

主要讲讲更新节点

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

1

2

3

// refreshNode:要刷新的节点;newNodeData:新的子节点数据

refreshNode.splice(0, refreshNode.length);

refreshNode.doCreateChildren(newNodeData);

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

1

2

3

4

menuNodeClick(data, node, treeNode) {

    this.selectNodeData = data

    this.selectNode = node

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

/**

* 刷新节点数据

* @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.单选:
如果在懒加载中,有单选项,则设置选中即可:

1

2

3

4

// 设置当前节点选中

this.$refs.tree.setCurrentKey(

    this.selectNodeData[this.nodeKey]

)

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

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

[

    {

        ...,

        children: [

            {

                ...,

                children: [

                    {

                        ...,

                        children: [...],

                    },

                    {

                        ...,

                        children: [...],

                    }

                ]

            },

            {

                ...,

                children: [

                    {

                        ...,

                        children: [...],

                    }

                ]

            }

        ]

    }

     

]

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

懒加载示例:
HTML控件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<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里面定义变量

1

2

3

4

5

6

7

8

9

// 树形菜单

     treeData: [], // 树节点

     defaultProps: { // 修改el-tree默认data数组参数

       children: 'children',

       label: 'name',

       id: 'id',

       parentId: 'parentId',

       isLeaf: 'leaf' // 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效

     },

methods:
加载树形菜单部分

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

// 加载 树数据

   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()

   },

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

// 树节点增加 类型规格

   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

1

2

this.$message('编辑成功')

             this.loadNodeTree(this.addnode.parent)

1.设置展开和收缩

1

2

3

4

5

if (!node.expanded) {

    node.expand();

}else {

    node.collapse();

}

2.获取父节点

1

node.parent

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


相关推荐

PHP实现部分字符隐藏

沙雕mars · 1319浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 903浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 964浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 959浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1084浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页