Browse Source

feat(tree): add renderIcon props close #309

Vben 4 years ago
parent
commit
72b42d7b35

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -11,6 +11,7 @@
 - 新增修改密码界面
 - 新增部门管理示例界面
 - 新增 WebSocket 示例和服务脚本
+- BasicTree 组件新增 `renderIcon` 属性用于控制层级图标显示
 
 ### ⚡ Performance Improvements
 

+ 2 - 3
src/components/Tree/index.ts

@@ -1,6 +1,5 @@
-import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
-
-export const BasicTree = createAsyncComponent(() => import('./src/BasicTree'));
+import BasicTree from './src/index.vue';
 
+export { BasicTree };
 export type { ContextMenuItem } from '/@/hooks/web/useContextMenu';
 export * from './src/types';

+ 0 - 219
src/components/Tree/src/BasicTree.tsx

@@ -1,219 +0,0 @@
-import './index.less';
-
-import type { ReplaceFields, TreeItem, Keys, CheckKeys, TreeActionType } from './types';
-
-import { defineComponent, reactive, computed, unref, ref, watchEffect, CSSProperties } from 'vue';
-import { Tree } from 'ant-design-vue';
-import { DownOutlined } from '@ant-design/icons-vue';
-
-import { useContextMenu, ContextMenuItem } from '/@/hooks/web/useContextMenu';
-
-import { isFunction } from '/@/utils/is';
-import { omit } from 'lodash-es';
-import { extendSlots } from '/@/utils/helper/tsxHelper';
-
-import { basicProps } from './props';
-import { useTree } from './useTree';
-import { useExpose } from '/@/hooks/core/useExpose';
-import { onMounted } from 'vue';
-
-interface State {
-  expandedKeys: Keys;
-  selectedKeys: Keys;
-  checkedKeys: CheckKeys;
-}
-const prefixCls = 'basic-tree';
-export default defineComponent({
-  name: 'BasicTree',
-  props: basicProps,
-  emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'get'],
-  setup(props, { attrs, slots, emit }) {
-    const state = reactive<State>({
-      expandedKeys: props.expandedKeys || [],
-      selectedKeys: props.selectedKeys || [],
-      checkedKeys: props.checkedKeys || [],
-    });
-
-    const treeDataRef = ref<TreeItem[]>([]);
-
-    const [createContextMenu] = useContextMenu();
-
-    const getReplaceFields = computed(
-      (): Required<ReplaceFields> => {
-        const { replaceFields } = props;
-        return {
-          children: 'children',
-          title: 'title',
-          key: 'key',
-          ...replaceFields,
-        };
-      }
-    );
-
-    const getContentStyle = computed(
-      (): CSSProperties => {
-        const { actionList } = props;
-        const width = actionList.length * 18;
-        return {
-          width: `calc(100% - ${width}px)`,
-        };
-      }
-    );
-
-    const getBindValues = computed(() => {
-      let propsData = {
-        blockNode: true,
-        ...attrs,
-        ...props,
-        expandedKeys: state.expandedKeys,
-        selectedKeys: state.selectedKeys,
-        checkedKeys: state.checkedKeys,
-        replaceFields: unref(getReplaceFields),
-        'onUpdate:expandedKeys': (v: Keys) => {
-          state.expandedKeys = v;
-          emit('update:expandedKeys', v);
-        },
-        'onUpdate:selectedKeys': (v: Keys) => {
-          state.selectedKeys = v;
-          emit('update:selectedKeys', v);
-        },
-        onCheck: (v: CheckKeys) => {
-          state.checkedKeys = v;
-          emit('update:value', v);
-        },
-        onRightClick: handleRightClick,
-      };
-      propsData = omit(propsData, 'treeData');
-      return propsData;
-    });
-
-    const getTreeData = computed((): TreeItem[] => unref(treeDataRef));
-
-    const { deleteNodeByKey, insertNodeByKey, filterByLevel, updateNodeByKey } = useTree(
-      treeDataRef,
-      getReplaceFields
-    );
-
-    //  渲染操作按钮
-    function renderAction(node: TreeItem) {
-      const { actionList } = props;
-
-      if (!actionList || actionList.length === 0) return;
-
-      return actionList.map((item, index) => {
-        return (
-          <span key={index} class={`${prefixCls}__action`}>
-            {item.render(node)}
-          </span>
-        );
-      });
-    }
-    // 渲染树节点
-    function renderTreeNode({ data }: { data: TreeItem[] | undefined }) {
-      if (!data) {
-        return null;
-      }
-      return data.map((item) => {
-        const { title: titleField, key: keyField, children: childrenField } = unref(
-          getReplaceFields
-        );
-        const propsData = omit(item, 'title');
-        const anyItem = item as any;
-        return (
-          <Tree.TreeNode {...propsData} key={anyItem?.[keyField]}>
-            {{
-              title: () => (
-                <span class={`${prefixCls}-title`}>
-                  <span class={`${prefixCls}__content`} style={unref(getContentStyle)}>
-                    {titleField && anyItem[titleField]}
-                  </span>
-                  <span class={`${prefixCls}__actions`}> {renderAction(item)}</span>
-                </span>
-              ),
-              default: () => renderTreeNode({ data: childrenField ? anyItem[childrenField] : [] }),
-            }}
-          </Tree.TreeNode>
-        );
-      });
-    }
-
-    // 处理右键事件
-    async function handleRightClick({ event, node }: any) {
-      const { rightMenuList: menuList = [], beforeRightClick } = props;
-      let rightMenuList: ContextMenuItem[] = [];
-      if (beforeRightClick && isFunction(beforeRightClick)) {
-        rightMenuList = await beforeRightClick(node);
-      } else {
-        rightMenuList = menuList;
-      }
-      if (!rightMenuList.length) return;
-      createContextMenu({
-        event,
-        items: rightMenuList,
-      });
-    }
-
-    function setExpandedKeys(keys: string[]) {
-      state.expandedKeys = keys;
-    }
-
-    function getExpandedKeys() {
-      return state.expandedKeys;
-    }
-    function setSelectedKeys(keys: string[]) {
-      state.selectedKeys = keys;
-    }
-
-    function getSelectedKeys() {
-      return state.selectedKeys;
-    }
-
-    function setCheckedKeys(keys: CheckKeys) {
-      state.checkedKeys = keys;
-    }
-
-    function getCheckedKeys() {
-      return state.checkedKeys;
-    }
-
-    watchEffect(() => {
-      treeDataRef.value = props.treeData as TreeItem[];
-      state.expandedKeys = props.expandedKeys;
-      state.selectedKeys = props.selectedKeys;
-      state.checkedKeys = props.checkedKeys;
-    });
-
-    const instance: TreeActionType = {
-      setExpandedKeys,
-      getExpandedKeys,
-      setSelectedKeys,
-      getSelectedKeys,
-      setCheckedKeys,
-      getCheckedKeys,
-      insertNodeByKey,
-      deleteNodeByKey,
-      updateNodeByKey,
-      filterByLevel: (level: number) => {
-        state.expandedKeys = filterByLevel(level);
-      },
-    };
-
-    useExpose<TreeActionType>(instance);
-
-    onMounted(() => {
-      emit('get', instance);
-    });
-
-    return () => {
-      return (
-        <Tree {...(unref(getBindValues) as any)} class={prefixCls}>
-          {{
-            switcherIcon: () => <DownOutlined />,
-            default: () => renderTreeNode({ data: unref(getTreeData) }),
-            ...extendSlots(slots),
-          }}
-        </Tree>
-      );
-    };
-  },
-});

+ 17 - 0
src/components/Tree/src/TreeIcon.ts

@@ -0,0 +1,17 @@
+import type { VNode, FunctionalComponent } from 'vue';
+
+import { h } from 'vue';
+import { isString } from '/@/utils/is';
+import { Icon } from '/@/components/Icon';
+
+export interface ComponentProps {
+  icon: VNode | string;
+}
+
+export const TreeIcon: FunctionalComponent = ({ icon }: ComponentProps) => {
+  if (!icon) return null;
+  if (isString(icon)) {
+    return h(Icon, { icon, class: 'mr-1' });
+  }
+  return Icon;
+};

+ 0 - 35
src/components/Tree/src/index.less

@@ -1,35 +0,0 @@
-.basic-tree {
-  position: relative;
-
-  &-title {
-    position: relative;
-    display: inline-block;
-    width: 100%;
-    padding-right: 10px;
-
-    &:hover {
-      .basic-tree__action {
-        visibility: visible;
-      }
-    }
-  }
-
-  &__content {
-    display: inline-block;
-    overflow: hidden;
-  }
-
-  &__actions {
-    position: absolute;
-    top: 0;
-    right: 0;
-    display: flex;
-  }
-
-  &__action {
-    margin-left: 4px;
-    // float: right;
-    // display: none;
-    visibility: hidden;
-  }
-}

+ 281 - 0
src/components/Tree/src/index.vue

@@ -0,0 +1,281 @@
+<script lang="tsx">
+  import type { ReplaceFields, Keys, CheckKeys, TreeActionType, TreeItem } from './types';
+
+  import { defineComponent, reactive, computed, unref, ref, watchEffect, onMounted } from 'vue';
+  import { Tree } from 'ant-design-vue';
+  import { TreeIcon } from './TreeIcon';
+  // import { DownOutlined } from '@ant-design/icons-vue';
+
+  import { omit, get } from 'lodash-es';
+  import { isFunction } from '/@/utils/is';
+  import { extendSlots } from '/@/utils/helper/tsxHelper';
+
+  import { useTree } from './useTree';
+  import { useContextMenu, ContextMenuItem } from '/@/hooks/web/useContextMenu';
+  import { useExpose } from '/@/hooks/core/useExpose';
+  import { useDesign } from '/@/hooks/web/useDesign';
+
+  import { basicProps } from './props';
+
+  interface State {
+    expandedKeys: Keys;
+    selectedKeys: Keys;
+    checkedKeys: CheckKeys;
+  }
+  export default defineComponent({
+    name: 'BasicTree',
+    props: basicProps,
+    emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'get'],
+    setup(props, { attrs, slots, emit }) {
+      const state = reactive<State>({
+        expandedKeys: props.expandedKeys || [],
+        selectedKeys: props.selectedKeys || [],
+        checkedKeys: props.checkedKeys || [],
+      });
+
+      const treeDataRef = ref<TreeItem[]>([]);
+
+      const [createContextMenu] = useContextMenu();
+      const { prefixCls } = useDesign('basic-tree');
+
+      const getReplaceFields = computed(
+        (): Required<ReplaceFields> => {
+          const { replaceFields } = props;
+          return {
+            children: 'children',
+            title: 'title',
+            key: 'key',
+            ...replaceFields,
+          };
+        }
+      );
+
+      // const getContentStyle = computed(
+      //   (): CSSProperties => {
+      //     const { actionList } = props;
+      //     const width = actionList.length * 18;
+      //     return {
+      //       width: `calc(100% - ${width}px)`,
+      //     };
+      //   }
+      // );
+
+      const getBindValues = computed(() => {
+        let propsData = {
+          blockNode: true,
+          ...attrs,
+          ...props,
+          expandedKeys: state.expandedKeys,
+          selectedKeys: state.selectedKeys,
+          checkedKeys: state.checkedKeys,
+          replaceFields: unref(getReplaceFields),
+          'onUpdate:expandedKeys': (v: Keys) => {
+            state.expandedKeys = v;
+            emit('update:expandedKeys', v);
+          },
+          'onUpdate:selectedKeys': (v: Keys) => {
+            state.selectedKeys = v;
+            emit('update:selectedKeys', v);
+          },
+          onCheck: (v: CheckKeys, e) => {
+            state.checkedKeys = v;
+            console.log(e);
+            emit('update:value', v);
+          },
+          onRightClick: handleRightClick,
+        };
+        propsData = omit(propsData, 'treeData');
+        return propsData;
+      });
+
+      const getTreeData = computed((): TreeItem[] => unref(treeDataRef));
+
+      const { deleteNodeByKey, insertNodeByKey, filterByLevel, updateNodeByKey } = useTree(
+        treeDataRef,
+        getReplaceFields
+      );
+
+      function getIcon(params: Recordable, icon?: string) {
+        if (!icon) {
+          if (props.renderIcon && isFunction(props.renderIcon)) {
+            return props.renderIcon(params);
+          }
+        }
+        return icon;
+      }
+
+      function renderAction(node: TreeItem) {
+        const { actionList } = props;
+        if (!actionList || actionList.length === 0) return;
+        return actionList.map((item, index) => {
+          return (
+            <span key={index} class={`${prefixCls}__action`}>
+              {item.render(node)}
+            </span>
+          );
+        });
+      }
+
+      function renderTreeNode({ data, level }: { data: TreeItem[] | undefined; level: number }) {
+        if (!data) {
+          return null;
+        }
+        return data.map((item) => {
+          const { title: titleField, key: keyField, children: childrenField } = unref(
+            getReplaceFields
+          );
+
+          const propsData = omit(item, 'title');
+          const icon = getIcon({ ...item, level }, item.icon);
+          return (
+            <Tree.TreeNode {...propsData} key={get(item, keyField)}>
+              {{
+                title: () => (
+                  <span class={`${prefixCls}-title`}>
+                    {icon && <TreeIcon icon={icon} />}
+                    <span
+                      class={`${prefixCls}__content`}
+                      //  style={unref(getContentStyle)}
+                    >
+                      {get(item, titleField)}
+                    </span>
+                    <span class={`${prefixCls}__actions`}> {renderAction(item)}</span>
+                  </span>
+                ),
+                default: () =>
+                  renderTreeNode({ data: get(item, childrenField) || [], level: level + 1 }),
+              }}
+            </Tree.TreeNode>
+          );
+        });
+      }
+
+      async function handleRightClick({ event, node }: any) {
+        const { rightMenuList: menuList = [], beforeRightClick } = props;
+        let rightMenuList: ContextMenuItem[] = [];
+
+        if (beforeRightClick && isFunction(beforeRightClick)) {
+          rightMenuList = await beforeRightClick(node);
+        } else {
+          rightMenuList = menuList;
+        }
+        if (!rightMenuList.length) return;
+        createContextMenu({
+          event,
+          items: rightMenuList,
+        });
+      }
+
+      function setExpandedKeys(keys: string[]) {
+        state.expandedKeys = keys;
+      }
+
+      function getExpandedKeys() {
+        return state.expandedKeys;
+      }
+      function setSelectedKeys(keys: string[]) {
+        state.selectedKeys = keys;
+      }
+
+      function getSelectedKeys() {
+        return state.selectedKeys;
+      }
+
+      function setCheckedKeys(keys: CheckKeys) {
+        state.checkedKeys = keys;
+      }
+
+      function getCheckedKeys() {
+        return state.checkedKeys;
+      }
+
+      watchEffect(() => {
+        treeDataRef.value = props.treeData as TreeItem[];
+        state.expandedKeys = props.expandedKeys;
+        state.selectedKeys = props.selectedKeys;
+        state.checkedKeys = props.checkedKeys;
+      });
+
+      const instance: TreeActionType = {
+        setExpandedKeys,
+        getExpandedKeys,
+        setSelectedKeys,
+        getSelectedKeys,
+        setCheckedKeys,
+        getCheckedKeys,
+        insertNodeByKey,
+        deleteNodeByKey,
+        updateNodeByKey,
+        filterByLevel: (level: number) => {
+          state.expandedKeys = filterByLevel(level);
+        },
+      };
+
+      useExpose<TreeActionType>(instance);
+
+      onMounted(() => {
+        emit('get', instance);
+      });
+
+      return () => {
+        return (
+          <Tree {...unref(getBindValues)} showIcon={false} class={[prefixCls]}>
+            {{
+              // switcherIcon: () => <DownOutlined />,
+              default: () => renderTreeNode({ data: unref(getTreeData), level: 1 }),
+              ...extendSlots(slots),
+            }}
+          </Tree>
+        );
+      };
+    },
+  });
+</script>
+<style lang="less">
+  @prefix-cls: ~'@{namespace}-basic-tree';
+
+  .@{prefix-cls} {
+    position: relative;
+
+    .ant-tree-node-content-wrapper {
+      position: relative;
+
+      .ant-tree-title {
+        position: absolute;
+        left: 0;
+        width: 100%;
+      }
+    }
+
+    &-title {
+      position: relative;
+      display: flex;
+      align-items: center;
+      width: 100%;
+      padding-right: 10px;
+
+      &:hover {
+        .@{prefix-cls}__action {
+          visibility: visible;
+        }
+      }
+    }
+
+    &__content {
+      display: inline-block;
+      overflow: hidden;
+    }
+
+    &__actions {
+      position: absolute;
+      top: 2px;
+      right: 2px;
+      display: flex;
+    }
+
+    &__action {
+      margin-left: 4px;
+      visibility: hidden;
+    }
+  }
+</style>

+ 8 - 4
src/components/Tree/src/props.ts

@@ -1,14 +1,18 @@
-import { PropType } from 'vue';
-import type { ReplaceFields, TreeItem, ActionItem, Keys, CheckKeys } from './types';
+import type { PropType } from 'vue';
+import type { ReplaceFields, ActionItem, Keys, CheckKeys } from './types';
 import type { ContextMenuItem } from '/@/hooks/web/useContextMenu';
+import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
 
 export const basicProps = {
+  renderIcon: {
+    type: Function as PropType<(params: Recordable) => string>,
+  },
   replaceFields: {
     type: Object as PropType<ReplaceFields>,
   },
 
   treeData: {
-    type: Array as PropType<TreeItem[]>,
+    type: Array as PropType<TreeDataItem[]>,
   },
 
   actionList: {
@@ -50,7 +54,7 @@ export const treeNodeProps = {
     type: Object as PropType<ReplaceFields>,
   },
   treeData: {
-    type: Array as PropType<TreeItem[]>,
+    type: Array as PropType<TreeDataItem[]>,
     default: () => [],
   },
 };

+ 5 - 83
src/components/Tree/src/types.ts

@@ -1,88 +1,10 @@
+import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
 export interface ActionItem {
   render: (record: any) => any;
 }
 
-export interface TreeItem {
-  /**
-   * Class
-   * @description className
-   * @type string
-   */
-  class?: string;
-
-  /**
-   * Style
-   * @description style of tree node
-   * @type string | object
-   */
-  style?: string | object;
-
-  /**
-   * Disable Checkbox
-   * @description Disables the checkbox of the treeNode
-   * @default false
-   * @type boolean
-   */
-  disableCheckbox?: boolean;
-
-  /**
-   * Disabled
-   * @description Disabled or not
-   * @default false
-   * @type boolean
-   */
-  disabled?: boolean;
-
-  /**
-   * Icon
-   * @description customize icon. When you pass component, whose render will receive full TreeNode props as component props
-   * @type any (slot | slot-scope)
-   */
+export interface TreeItem extends TreeDataItem {
   icon?: any;
-
-  /**
-   * Is Leaf?
-   * @description Leaf node or not
-   * @default false
-   * @type boolean
-   */
-  isLeaf?: boolean;
-
-  /**
-   * Key
-   * @description Required property, should be unique in the tree
-   * (In tree: Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys)
-   * @default internal calculated position of treeNode or undefined
-   * @type string | number
-   */
-  key: string | number;
-
-  /**
-   * Selectable
-   * @description Set whether the treeNode can be selected
-   * @default true
-   * @type boolean
-   */
-  selectable?: boolean;
-
-  /**
-   * Title
-   * @description Content showed on the treeNodes
-   * @default '---'
-   * @type any (string | slot)
-   */
-  title: any;
-
-  /**
-   * Value
-   * @description Will be treated as treeNodeFilterProp by default, should be unique in the tree
-   * @default undefined
-   * @type string
-   */
-  value?: string;
-  children?: TreeItem[];
-  slots?: any;
-  scopedSlots?: any;
 }
 
 export interface ReplaceFields {
@@ -107,12 +29,12 @@ export interface TreeActionType {
   filterByLevel: (level: number) => void;
   insertNodeByKey: (opt: InsertNodeParams) => void;
   deleteNodeByKey: (key: string) => void;
-  updateNodeByKey: (key: string, node: Omit<TreeItem, 'key'>) => void;
+  updateNodeByKey: (key: string, node: Omit<TreeDataItem, 'key'>) => void;
 }
 
 export interface InsertNodeParams {
   parentKey: string | null;
-  node: TreeItem;
-  list?: TreeItem[];
+  node: TreeDataItem;
+  list?: TreeDataItem[];
   push?: 'push' | 'unshift';
 }

+ 9 - 8
src/components/Tree/src/useTree.ts

@@ -1,16 +1,17 @@
-import type { InsertNodeParams, ReplaceFields, TreeItem } from './types';
+import type { InsertNodeParams, ReplaceFields } from './types';
 import type { Ref, ComputedRef } from 'vue';
+import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
 
 import { cloneDeep } from 'lodash-es';
 import { unref } from 'vue';
 import { forEach } from '/@/utils/helper/treeHelper';
 
 export function useTree(
-  treeDataRef: Ref<TreeItem[]>,
+  treeDataRef: Ref<TreeDataItem[]>,
   getReplaceFields: ComputedRef<ReplaceFields>
 ) {
-  // 更新节点
-  function updateNodeByKey(key: string, node: TreeItem, list?: TreeItem[]) {
+  // Update node
+  function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) {
     if (!key) return;
     const treeData = list || unref(treeDataRef);
     const { key: keyField, children: childrenField } = unref(getReplaceFields);
@@ -30,8 +31,8 @@ export function useTree(
     }
   }
 
-  // 展开指定级别
-  function filterByLevel(level = 1, list?: TreeItem[], currentLevel = 1) {
+  // Expand the specified level
+  function filterByLevel(level = 1, list?: TreeDataItem[], currentLevel = 1) {
     if (!level) {
       return [];
     }
@@ -74,8 +75,8 @@ export function useTree(
     treeDataRef.value = treeData;
   }
 
-  // 删除节点
-  function deleteNodeByKey(key: string, list?: TreeItem[]) {
+  // Delete node
+  function deleteNodeByKey(key: string, list?: TreeDataItem[]) {
     if (!key) return;
     const treeData = list || unref(treeDataRef);
     const { key: keyField, children: childrenField } = unref(getReplaceFields);

+ 1 - 0
src/views/demo/tree/ActionTree.vue

@@ -35,6 +35,7 @@
     setup() {
       const treeRef = ref<Nullable<TreeActionType>>(null);
       const { createMessage } = useMessage();
+
       function getTree() {
         const tree = unref(treeRef);
         if (!tree) {

+ 15 - 3
src/views/demo/tree/EditTree.vue

@@ -1,8 +1,8 @@
 <template>
   <PageWrapper title="Tree函数操作示例">
     <div class="flex">
-      <CollapseContainer title="右侧操作按钮" class="mr-4" :style="{ width: '33%' }">
-        <BasicTree :treeData="treeData" :actionList="actionList" />
+      <CollapseContainer title="右侧操作按钮/自定义图标" class="mr-4" :style="{ width: '33%' }">
+        <BasicTree :treeData="treeData" :actionList="actionList" :renderIcon="createIcon" />
       </CollapseContainer>
 
       <CollapseContainer title="右键菜单" class="mr-4" :style="{ width: '33%' }">
@@ -61,7 +61,19 @@
           },
         },
       ];
-      return { treeData, actionList, getRightMenuList };
+
+      function createIcon({ level }) {
+        if (level === 1) {
+          return 'ion:git-compare-outline';
+        }
+        if (level === 2) {
+          return 'ion:home';
+        }
+        if (level === 3) {
+          return 'ion:airplane';
+        }
+      }
+      return { treeData, actionList, getRightMenuList, createIcon };
     },
   });
 </script>

+ 1 - 4
src/views/demo/tree/data.ts

@@ -2,9 +2,8 @@ import { TreeItem } from '/@/components/Tree/index';
 
 export const treeData: TreeItem[] = [
   {
-    title: 'parent 1parent ',
+    title: 'parent ',
     key: '0-0',
-    icon: 'home|svg',
     children: [
       { title: 'leaf', key: '0-0-0' },
       {
@@ -20,7 +19,6 @@ export const treeData: TreeItem[] = [
   {
     title: 'parent 2',
     key: '1-1',
-    icon: 'home|svg',
     children: [
       { title: 'leaf', key: '1-1-0' },
       { title: 'leaf', key: '1-1-1' },
@@ -29,7 +27,6 @@ export const treeData: TreeItem[] = [
   {
     title: 'parent 3',
     key: '2-2',
-    icon: 'home|svg',
     children: [
       { title: 'leaf', key: '2-2-0' },
       { title: 'leaf', key: '2-2-1' },