站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        怎么定制Ant Design樹形組件實現(xiàn)編輯、搜索和反向定位功能?下面本篇文章給大家介紹一下創(chuàng)建樹形組件,實現(xiàn)這些功能的方法,希望對大家有所幫助!

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        這次在做了一個樹形的展示功能,誰知產(chǎn)品意猶未盡,找我談話:

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

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

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

        YY: 話是這樣說,可事情不是這么做的…

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

        YY: …

        以上故事純屬虛構,如有雷同請評論區(qū)留言…

        樹形數(shù)據(jù)在開發(fā)中算是比較常見了,文件夾、組織架構、生物分類、國家地區(qū)等等,世間萬物的大多數(shù)結(jié)構都是樹形結(jié)構。使用樹控件可以完整展現(xiàn)其中的層級關系,并具有展開收起選擇等交互功能。

        需求分析

        • 編輯:添加/修改/刪除/移動
        • 搜索功能:名稱/創(chuàng)建人/ owner過濾
        • 定位:tab反向定位

        項目倉庫:https://github.com/speakice/editable-tree

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        功能實現(xiàn)

        能實現(xiàn)以上功能的方法庫和組件有很多種,這里只講其中一種,都是Ant Design的組件:

        • Tree.DirectoryTree 目錄樹
        • Dropdown 右鍵菜單容器
        • Menu 菜單內(nèi)容
        • Tabs 右側(cè)Tab頁
        • Input.Search 搜索框
        • Switch 切換關聯(lián)狀態(tài)
        • shortid 生成唯一id
        import { Tree, Dropdown, Menu, Tabs, Input, Switch } from 'antd';import shortid from 'shortid';復制代碼

        遞歸方法

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

        /**  * 如果需要修改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寫入樹形組件的數(shù)據(jù)源上:

            <DirectoryTree           style={{ width: 280 }}           draggable           onDrop={onDrop}           defaultExpandAll           onRightClick={({ node }) => setRightClickKey(node.key)}           onSelect={onSelect}           selectedKeys={rightConnect ? [activeTabKey] : selectedKeys}           onExpand={onExpand}           treeData={[             ...deepTree(treeData, (item) => {              return {                 ...item,                titleWord: item.title,                title: (                  <Dropdown                    trigger="contextMenu"                    visible={rightClickKey === item.key}                    onVisibleChange={() => setRightClickKey()}                     overlayStyle={{ width: 80 }}                     overlay={menu(item)}                   >                    <div                      style={                        searchWord && item.title.includes(searchWord)                           ? { color: 'red' }                          : {}                       }                     >                       {item.title}                    </div>                  </Dropdown>                 ),               };             }),           ]}         />復制代碼

        關于右鍵菜單有幾點需要補充說明一下:

        • Dropdown 的觸發(fā)屬性需要設置成contextMenu;
        • Dropdown 顯示的位置是相對于title而言,需要設置外層容器寬度鋪滿剩余空間:
        .ant-tree-node-content-wrapper {  display: flex; }.ant-tree-title {  flex: 1; }復制代碼
        • Dropdown 的顯示藏是通過右鍵點擊記錄的key來判斷的;
        • Dropdown 的菜單需要傳遞當前item;
          const menu = (node) => (    <Menu      onClick={({ key, domEvent }) => {         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 key="add">新增</Menu.Item>      <Menu.Item key="delete" danger>         刪除      </Menu.Item>      <Menu.Item key="edit">編輯</Menu.Item>    </Menu>   );復制代碼

        添加/修改/刪除功能

        添加功能默認只能給文件夾添加,通過key值判斷添加,這里處理的比較簡單,只做核心功能演示,代碼見上一小節(jié);

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        修改功能也做了簡單的實例,在正式項目中一般需要彈窗編輯或者在樹組件的title中嵌入輸入框,可以使用變量記錄正在編輯的item, 最后保存通過遞歸插入到樹形數(shù)據(jù)中:

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

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

        搜索功能

        搜索功能是通過titile顏色變紅來提示的:

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        實現(xiàn)上也只是做了點擊搜索之后搜索,沒有實時搜索提示,也沒有做搜索詞區(qū)分,這里可以再截取下字符串來實現(xiàn),可以見官方實例,注意這個默認打開父節(jié)點的屬性autoExpandParent,否則可能要費些功夫向上遞歸。

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        還有一種需求是要過濾數(shù)據(jù)源,可以對官方實例簡單改造后實現(xiàn);

        Tab反向定位

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        點擊Tree組件item,在右側(cè)添加Tab,或者激活Tab,這可以算是正向定位;那反向定位就是當右側(cè)Tab頁切換時左側(cè)Tree組件選中對應item,核心代碼也就是指定selectedKeys,相比較而言也不難,難點在默認打開相關父節(jié)點,當然前面說過了控制好autoExpandParent這個屬性,就好了。

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        拖拽移動

        拖拽移動一是Tree組件本身支持,二是官方已經(jīng)給出了拖拽移動實例,我也只是在官方實例稍微做了改造,這里也不多贅述:

        Ant Design創(chuàng)建一個樹形組件,實現(xiàn)編輯、搜索和定位功能

        結(jié)束

        搜索和反向定位的難點其實是在,打開關聯(lián)文件夾上,不過官方實例中使用了autoExpandParent這個屬性,一下子簡單了很多。

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

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 精品亚洲欧美无人区乱码| 99久久精品国产一区二区| 四虎国产精品永久地址入口| 国产精品无码a∨精品| 免费精品精品国产欧美在线欧美高清免费一级在线 | 国产精品igao视频网| 亚洲精品专区在线观看| 精品久久久久久无码人妻热| 亚洲国产精品lv| 91麻豆精品国产自产在线观看亚洲| 亚洲а∨天堂久久精品| 精品人妻V?出轨中文字幕| 国产成人无码精品一区在线观看 | 99热都是精品久久久久久| 婷婷五月深深久久精品| 亚洲精品成人无码中文毛片不卡| 国产香蕉国产精品偷在线观看| 精品久久久久久无码国产| 综合在线视频精品专区| 亚洲AV永久青草无码精品| 国产精品一区三区| 99久久人人爽亚洲精品美女| 992tv精品视频tv在线观看| 久久这里只有精品18| 91自慰精品亚洲| 国产成人久久精品区一区二区| 精品人妻久久久久久888| 亚洲国产精品特色大片观看完整版| 亚欧乱色国产精品免费视频 | 亚洲无码精品浪潮| 欧美国产成人久久精品 | 久久久久久夜精品精品免费啦| 国产精品欧美亚洲韩国日本不卡| 国产精品自在拍一区二区不卡| 国产韩国精品一区二区三区久久| 成人精品一区二区三区中文字幕| 国产中老年妇女精品| 1024国产欧美日韩精品| 东京热TOKYO综合久久精品| 99视频精品全部在线观看| 国产精品无码a∨精品|