首頁 >web前端 >前端問答 >Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

青灯夜游
青灯夜游轉載
2022-01-13 18:28:214309瀏覽

怎麼客製化Ant Design樹形元件實現編輯、搜尋和反向定位功能?以下這篇文章為大家介紹一下建立樹形組件,實現這些功能的方法,希望對大家有幫助!

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

這次在做了一個樹狀的展示功能,誰知產品意猶未盡,找我談話:

PD: 什麼?只有展開收起功能?這怎麼行,咱們最基礎的要支持編輯,支持搜索,如果可以的話還可以做個反向定位...

YY: 你咋不早說?需求文件上也沒有啊...

PD: 你看誰家文檔一次寫到位的?哪一個的PD不加需求?

YY: 話是這樣說,可事情不是這麼做的...

PD: 哎呀,別杵著浪費時間了,快去做吧!

YY: ...

以上故事純屬虛構,如有雷同請留言區留言...

樹形資料在開發中算是比較常見了,資料夾、組織架構、生物分類、國家地區等等,世間萬物的大多數結構都是樹狀結構。使用樹狀控制可以完整展現其中的層級關係,並具有展開收起選擇等互動功能。

需求分析

  • 編輯:新增/修改/刪除/移動
  • #搜尋功能:姓名/建立人/ owner過濾
  • 定位: tab反向定位

專案倉庫:https://github.com/speakice/editable-tree

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

功能實作

能實現以上功能的方法庫和元件有很多種,這裡只講其中一種,都是Ant Design的元件:

  • Tree.DirectoryTree 目錄樹
  • Dropdown右鍵選單容器
  • Menu 選單內容
  • Tabs 右側Tab頁
  • Input.Search 搜尋框
  • Switch 切換關聯狀態
  • # shortid 產生唯一id
import { Tree, Dropdown, Menu, Tabs, Input, Switch } from 'antd';import shortid from 'shortid';复制代码

遞歸方法

操作樹行數據,最重要的前提是要有一個趁手的遞歸方法:

/**
 * 如果需要修改tree,action就返回修改后的item, 不修改就不返回
 */export const deepTree = (tree = [], action = () => {}) => {  return tree.map((item) => {    const newItem = action({ ...item }) || item;    if (newItem.children) {
      newItem.children = deepTree(newItem.children, action);
    }    return newItem;
  });
};复制代码

滑鼠右鍵選單

右鍵選單作用在title上,需要把Dropdown寫入樹狀元件的資料來源上:

    <directorytree> setRightClickKey(node.key)}
          onSelect={onSelect}
          selectedKeys={rightConnect ? [activeTabKey] : selectedKeys}
          onExpand={onExpand}
          treeData={[
            ...deepTree(treeData, (item) => {              return {
                ...item,                titleWord: item.title,                title: (                  <dropdown> setRightClickKey()}
                    overlayStyle={{ width: 80 }}
                    overlay={menu(item)}
                  >                    <div>
                      {item.title}                    </div>                  </dropdown>
                ),
              };
            }),
          ]}
        />复制代码</directorytree>

關於右鍵選單有幾點需要補充說明:

  • #Dropdown 的觸發屬性需要設定成contextMenu;
  • Dropdown 顯示的位置是相對於title而言,需要設定外層容器寬度鋪滿剩餘空間:
.ant-tree-node-content-wrapper {  display: flex;
}.ant-tree-title {  flex: 1;
}复制代码
  • Dropdown 的顯示藏是透過右鍵點擊記錄的key來判斷的;
  • Dropdown 的選單需要傳遞目前item;
  const menu = (node) => (    <menu> {
        domEvent.stopPropagation();
        console.log('menuClick', node, key);
        // 如果要添加操作顶层文件夹,可以直接操作
        switch (key) {
          case 'add':
            setTreeData(
              deepTree(treeData, (item) => {
                if (item.children && item.key === node.key) {
                  return {
                    ...item,
                    children: [
                      ...item.children,
                      {
                        title: 'new add',
                        key: shortid.generate(),
                        isLeaf: true,
                      },
                    ],
                  };
                }
              })
            );
            break;
          case 'delete':
            const outer = treeData.find((item) => item.key === node.key);
            if (outer) {
              setTreeData(treeData.filter((item) => item.key !== node.key));
              return;
            }
            setTreeData(
              deepTree(treeData, (item) => {
                if (item.children) {
                  return {
                    ...item,
                    children: item.children.filter(
                      ({ key }) => key !== node.key
                    ),
                  };
                }
                return item;
              })
            );
            break;
          case 'edit':
            setTreeData(
              deepTree(treeData, (item) => {
                if (item.key === node.key) {
                  console.log('editle', {
                    ...item,
                    title: 'new edit',
                  });
                  return {
                    ...item,
                    title: 'new edit',
                  };
                }
                return item;
              })
            );
            break;
        }
      }}
    >      <menu.item>新增</menu.item>      <menu.item>
        删除      </menu.item>      <menu.item>编辑</menu.item>    </menu>
  );复制代码

新增/修改/移除功能

添加功能預設只能給資料夾添加,透過key值判斷添加,這裡處理的比較簡單,只做核心功能演示,程式碼見上一小節;

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

修改功能也做了簡單的實例,在正式專案中一般需要彈窗編輯或在樹組件的title中嵌入輸入框,可以使用變數記錄正在編輯的item, 最後保存透過遞歸插入到樹形數據中:

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

刪除功能做了判斷,如果是刪除最外層,則直接透過filter過濾,⚠️否則刪除功能是透過children來過濾的,這裡要特別注意下。

搜尋功能

搜尋功能是透過titile顏色變紅來提示的:

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

實作上也只是做了點擊搜尋之後搜索,沒有實時搜索提示,也沒有做搜索詞區分,這裡可以再截取下字符串來實現,可以見官方實例注意這個默認打開父節點的屬性autoExpandParent ,否則可能要花點功夫向上遞歸。

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

還有一個需求是要過濾資料來源,可以簡單地對官方實例進行改造;

Tab反向定位

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

點選Tree元件item,在右邊加入Tab,或是啟動Tab,這可以算是正向定位;那反向定位就是當右側Tab頁切換時左側Tree元件選取對應item,核心程式碼也就是指定selectedKeys,相比較而言也不難,難點在預設開啟相關父節點,當然前面說過了控制好autoExpandParent這個屬性,就好了。

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

拖曳移動

拖曳移動一是Tree組件本身支持,二是官方已經給了拖曳移動實例,我也只是在官方實例稍微做了改造,這裡也不多贅述:

Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能

#結束

搜尋和反向定位的難點其實是在,開啟關聯資料夾上,不過官方實例中使用了autoExpandParent這個屬性,一下子簡單了很多。

時候也不早了,今天就到這裡了。

更多程式相關知識,請造訪:程式設計影片! !

以上是Ant Design創建一個樹狀元件,實現編輯、搜尋和定位功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除