iview中tree树形组件使用介绍(个人总结)

it2024-02-21  78

iview中tree树形组件使用介绍

最近有用到tree,被官网简单的描述折磨得有点小难受,上手后小有所得,在此和大家分享,希望大佬们不吝指教。

先贴官方的代码,简单看一下

<template> <Tree :data="data5" :render="renderContent" class="demo-tree-render"></Tree> </template> <script> export default { data() { return { data5: [ { title: "parent 1", expand: true, render: (h, { root, node, data }) => { //根节点的debugger(G0) return h( "span", { style: { display: "inline-block", width: "100%", }, }, [ h("span", [ h("Icon", { props: { type: "ios-folder-outline", }, style: { marginRight: "8px", }, }), h("span", data.title), ]), h( "span", { style: { display: "inline-block", float: "right", marginRight: "32px", }, }, [ h("Button", { props: Object.assign({}, this.buttonProps, { icon: "ios-add", type: "primary", }), style: { width: "64px", }, on: { click: () => { this.append(data); }, }, }), ] ), ] ); }, children: [ { title: "child 1-1", expand: true, children: [ { title: "leaf 1-1-1", expand: true, }, { title: "leaf 1-1-2", expand: true, }, ], }, { title: "child 1-2", expand: true, children: [ { title: "leaf 1-2-1", expand: true, }, { title: "leaf 1-2-1", expand: true, }, ], }, ], }, ], buttonProps: { type: "default", size: "small", }, }; }, methods: { renderContent(h, { root, node, data }) { return h( "span", { style: { display: "inline-block", width: "100%", }, }, [ h("span", [ h("Icon", { props: { type: "ios-paper-outline", }, style: { marginRight: "8px", }, }), h("span", data.title), ]), h( "span", { style: { display: "inline-block", float: "right", marginRight: "32px", }, }, [ h("Button", { props: Object.assign({}, this.buttonProps, { icon: "ios-add", }), style: { marginRight: "8px", }, on: { click: () => { this.append(data); }, }, }), h("Button", { props: Object.assign({}, this.buttonProps, { icon: "ios-remove", }), on: { click: () => { this.remove(root, node, data); }, }, }), ] ), ] ); }, append(data) { const children = data.children || []; children.push({ title: "appended node", expand: true, }); this.$set(data, "children", children); }, remove(root, node, data) { const parentKey = root.find((el) => el === node).parent; const parent = root.find((el) => el.nodeKey === parentKey).node; const index = parent.children.indexOf(data); parent.children.splice(index, 1); }, }, }; </script>

效果图如下

先简单的介绍一下render函数,包含两个参数"h","{root, node, data}"。本着先来后到的原则,我们先讲一下第二个参数。

第二个参数包括root,node,data这三个参数。 root:根节点 node:当前节点 data:当前节点的数据 在根节点下面打一个debugger(代号G0),让我们一起看一下返回值~

root的图

由上到下的顺序来挨个说一下 1.children(子节点的序号,从0开始,和nodekey保持一致) 2.node(包含子节点的属性) 1)children:子节点的子节点的属性(套娃) 2)expand:目标节点是否展开 true-展开,false-折叠 3)nodekey:目标节点的序号,不按照层级,只从上到下计算 4)render:目标节点的渲染函数 5)title:目标节点的内容

本人的懒病发作,node和data的属性与root大同小异,就不在一一讲解。

上面讲了render的第二个参数,咱们回头讲一下第一个参数"h"。

还是在G0的位置,console一下h,得到结果如下:

ƒ (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); }

点击跳转至js文件中的这一行 搜索createElement函数可得

a,b,c,d分别对于tag,data,children和normalizationType。接下来我们逐个分析:

1.h(“span”,b,c,d) 第一参数代表元素的tag,比如input,span,p。无法在后面加.赋予类名或#给予id

2.h(“span”,{class:“xxx”,style:“xxx”,attrs:{id:“xxx”,type:“xxx”,class:“xxx”}},c,d) 第二个参数data,即可以修改当前节点的属性,例如元素的class,style,type,id等属性,有两点需要提一句。 1).id只能放在attrs中声明,直接放在attrs外不起作用 2)如果在attrs外层和attrs内部都定义了一种属性,attrs外的优先级更大。

3.直接贴一段代码

render: (h, { root, node, data }) => { debugger; return h( "span", { class: "xxx", style: { display: "inline-block", width: "100%", }, }, [ h("span", [ h("Icon", { props: { type: "ios-folder-outline", }, style: { marginRight: "8px", }, }), h("span", data.title), ]), ] ); }

第三个参数children,代表渲染子元素的函数。

上面代码的效果 如下

可以写成如下(我是故意在标签上加点为了好看好玩来着,实际操作的时候请注意)

h("span",{class:'vvvvv'}, [ h("Icon", { props: { type: "ios-folder-outline", }, style: { marginRight: "8px", }, }), h("span.s",[ h("span.u",[ h("span.n","hello word!") ]) ]), ]),

这时候有认真看文章的朋友会发现问题了,在用h函数套娃的时候,第二个参数不传属性,反而传函数和内容了,这是为什么呢?

我看了看源码 if (Array.isArray(data) || isPrimitive(data)) { normalizationType = children; children = data; data = undefined; }

代码的含义是当data是 Array || string || number || symbol || bolean 的时候,把data的值赋给children。

第二个参数可以直接写children的渲染函数,也就符合上述情况:“参数是一个数组”;

同样的,直接写"hello word"的话,isPrimitive() 会返回true,所以也可以在h函数的第二个参数的位置写string或者number等。

至于h的最后一个参数d,感觉目前并不是很能用的到,有机会的话回头再聊。

最后,由于是自己琢磨出来的,可能会存在问题,希望大佬能帮忙指出,我看到就立刻修改,提前感谢一下大家了。

以上~

最新回复(0)