ElementPlus扩展-树组件

418 阅读3分钟

简介

扩展ElTree组件,自定义渲染节点,增加多个插槽、节点连接线。

运行效果

image.png

image.png

连接线实现

const renderLine = () => {
  const lineNodes: VNode[] = [];
  if (props.showLine) {
    // 取得每一层的当前节点是不是在当前层级列表的最后一个
    const firstNodeArr: boolean[] = [];
    const lastNodeArr: boolean[] = [];
    let currentNode = props.node as Partial<TreeNode & Node>;
    while (currentNode) {
      let parentNode = currentNode.parent as Partial<TreeNode & Node>;
      // 兼容element-plus的 el-tree-v2 (Virtualized Tree 虚拟树)
      if (currentNode.level === 1 && !currentNode.parent) {
        // el-tree-v2的第一层node是没有parent的,必需 treeData 创建一个parent
        if (!props.treeData || !Array.isArray(props.treeData)) {
          throw Error(
            "if you using el-tree-v2 (Virtualized Tree) of element-plus,element-tree-line required data."
          );
        }
        parentNode = {
          children: Array.isArray(props.treeData)
            ? props.treeData.map(item => {
              return {...item, key: props.getVirtualizedNodeKey(item) ?? item.id};
            }) as TreeNode[]
            : [],
          level: 0,
          key: "node-0",
          parent: undefined,
        };
      }
      if (parentNode) {
        const children = parentNode?.children || parentNode?.childNodes;
        // element-plus的 el-tree-v2 使用的是children和key, 其他使用的是 childNodes和id
        if (Array.isArray(children)) {
          const index = children.findIndex(item => (item.key || item.id) === (currentNode.key || currentNode.id));
          firstNodeArr.unshift(index === 0);
          lastNodeArr.unshift(index === children.length - 1);
        }
      }
      currentNode = parentNode;
    }
    for (let i = 0; i < props.node.level; i++) {
      const isFirst = firstNodeArr[i] && props.node.level === 1;
      const isLeaf = lastNodeArr[i] && props.node.level - 1 === i;
      lineNodes.push(h("span", {
        class: {
          [`${b('line-ver')}`]: true,
          "first-node-line": isFirst,
          "last-node-line": lastNodeArr[i] && props.node.level - 1 !== i,
          "last-node-line--is-leaf": isLeaf
        },
        style: {left: props.indent * i + "px"}
      }));
    }
    // 竖线
    lineNodes.push(h("span", {
      class: b('line-hor'),
      style: {
        width: (props.node.isLeaf ? 24 : 8) + "px",
        left: (props.node.level - 1) * props.indent + "px"
      }
    }));
  }
  return lineNodes;
};

Props

名称类型默认值说明必传
virtualizedboolean-是否渲染虚拟树N
filterableboolean-是否开启过滤N
showLineboolean-是否开启连接线N
heightnumber/string-高度N
offsetHeightnumber-自动计算高度时,偏差高度N
dataArray-树数据N
propsobject{label: 'label',value: 'value', children: 'children'}选项数据的配置 请参阅下面TreePropsN
emptyTextstring-为空的时候展示的文本N
highlightCurrentbooleanfalse是否高亮当前选中节点N
showCheckboxbooleanfalse节点是否可被选择N
checkStrictlybooleanfalse在显示复选框的情况下,是否严格的遵循父子不互相关联的做法N
defaultCheckedKeysArray-默认选中的节点的 key 的数组N
defaultExpandedKeysArray-默认展开的节点的 key 的数组N
indentnumber-相邻级节点间的水平缩进N
itemSizenumber-各节点高度N
iconstring-自定义树节点图标组件N
currentNodeKeystring-当前选中的节点N
expandOnClickNodebooleantrue是否在点击节点的时候展开或者收缩节点N
checkOnClickNodeboolean-是否在点击节点的时候选中节点N
accordionboolean-是否每次只打开一个同级树节点展开N
filterNodeMethodFunction-自定义过滤方法,方法参数(value, data, node)value为搜索关键字,data为节点数据N
loadImmediatebooleantrueapi是否主动加载数据N
apiFunction-选项数据加载apiN
beforeApiFetchFunction/object-请求api前调用返回值用于api携带参数N
parseApiDataFunction-解析api返回的数据N
apiEffectKeyFunction/string-动态加载apikey,值变化后会调用组件reload方法N

TreeProps

名称类型默认值说明
labelstringlabel指定节点标签为选项对象的某个属性值
valuestringvalue指定节点key为选项对象的某个属性值
childrenstringchildren指定节点的子选项为选项对象的某个属性值
disabledstring/Functiondisabled指定节点的禁用为选项对象的某个属性值/返回是否禁用
showstring/Function-指定节点是否显示为选项对象的某个属性值/返回是否显示
isLeafstring/Function-指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效/返回是否
classstring/Function-自定义节点类名/返回class
formatterFunction-节点显示格式化函数

Events

名称参数说明
loaded-options(data)绑定api时数据加载完成触发,data为api返回的树数据

Slots

名称参数说明
default({data, node})自定义节点内容,data为节点数据,node为树节点
icon({data, node})自定义图标内容,显示在节点前
action({data, node})自定义操作内容,显示在节点后
empty-无数据集时内容
toolbar-工具栏内容,显示在过滤输入框后

Exposes

名称类型说明
reload(params?:Record<string, unknown>)调用api重新加载选项数据,params为调用api携带的参数
bindOptionsData(data: Array<IOptionData>)重新绑定组件选项数据,data为选项数据