成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

Ant Design創建一個樹形組件,實現編輯、搜索和定位功能

怎么定制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           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 的觸發屬性需要設置成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值判斷添加,這里處理的比較簡單,只做核心功能演示,代碼見上一小節;

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這個屬性,一下子簡單了很多。

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

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
欧美最猛黑人XXXⅩ猛男无码| 欧洲熟妇色XXXXⅩ| 乱人伦人妻中文字幕无码| 蜜国产精品JK白丝AV网站| 欧美人与动牲交免费观看| 日本亲近相奷中文字幕| 天堂资源とまりせっくす| 亚洲 欧美 激情 另类 校园| 亚洲人成色77777| 中文字日产幕码三区做法 | 丰满少妇女裸体BBW| 国产精品毛片VA一区二区三区 | 亚洲国产成人无码网站大全| 一本久久伊人热热精品中文| 9L国产精品久久久久麻豆| 成人区精品一区二区不卡| 国产拍揄自揄精品视频| 久久精品国产999久久久| 欧美极品少妇做受| 天天曰天天躁天天摸孕妇| 亚洲精品无码AMM毛片| 717午夜伦伦电影理论片| 丰满熟妇乱子又伦| 精品深夜av无码一区二区老年| 亚洲最大的熟女水蜜桃AV网站| 中文字幕无码精品亚洲资源网| 饱满的乳被揉捏玩弄| 国产精品无码一区二区三区| 精品一区二区三区在线视频| 欧美精欧美乱码一二三四区| 天堂在/线资源中文在线| 亚洲区色情区激情区小说色情书| AV天堂永久资源网亚洲高清| 国产成人精品午夜福利 | 欧美日韩一区二区在线视频精品| 挺进绝色老师的紧窄小肉 | 亚洲不卡AV不卡一区二区| 中文字幕人妻无码乱精品| 给个网站2021年直接进入的| 精品无码久久久久久尤物| 秋霞午夜成人久久电影网| 亚洲AV素人乱码| 99久在线国内在线播放免费观看| 国产精品无码V在线观看| 美女粉嫩饱满的一线天MP4| 体验区试看120秒十八禁| 又小又紧女MAGNET| 国产成人无码精品久久二区三区| 久久久亚洲精品无码| 色综合AV男人的天堂伊人| 亚洲中文字幕AV在天堂| 大杳蕉在线影院在线播放| 久久99国产精品久久99| 日日摸夜夜添夜夜添无| 亚洲最新无码中文字幕久久| 高H纯肉放荡脏话H文合集| 久久久亚洲精品无码| 天天看AV片在线观看| 中国少妇BBWBBW| 国产精品自在在线午夜| 欧美极品少妇XXXXⅩ另类| 亚洲成人在线观看av| 潮喷失禁大喷水AⅤ无码 | 国产日韩亚洲大尺度高清| 欧美精品99久久久啪啪| 亚洲AV无码专区色爱天堂| 边喂奶边中出的人妻| 久久久久久精品免费无码无| 忘忧草视频在线观看| 99久久国产综合精品SWAG| 黑人巨大xxxx| 日韩人妻无码免费视频一区二区三 | ⅩXXⅩ互换人妻四人互换| 后入内射无码人妻一区| 日日狠狠久久偷偷四色综合免费| 中国在线观看免费高清完整版| 国产一精品一AV一免费| 日本在线观看母与子| 中国鲜肉GAY高中XX禁18网| 国产一区二区三区水蜜桃| 日韩v亚洲v欧美v精品综合| 真实的国产乱XXXX在线| 韩国无码无遮挡在线观看不卡| 色婷婷婷亚洲综合丁香五月| 51草莓看视频在线观看免费| 精品成人乱色一区二区| 天堂√最新版中文在线天堂| ぱらだいす天堂中文网WWW在线| 浪荡女天天不停挨CAO日常视频| 亚洲AV无码不卡一区二区三区 | 试看120秒做受小视频免费| 97色伦综合在线欧美视频| 久久精品国产亚洲AV高清色欲 | 婷婷五月六月综合缴情| JAPANESE国产在线观看播| 林静公交车被做到高C| 亚洲精品无码专区久久同性男| 国产精品毛片久久久久久久 | 亚洲熟悉妇女XXX妇女AV| 国产日产欧洲无码视频| 四季亚洲Av日韩AV无码中文 | 婷婷蜜桃国产精品一区| 成人精品视频一区二区不卡| 国产成人午夜高潮毛片| 全力以赴的行动派第二季| √天堂资源地址在线官网| 久久AV无码精品人妻系列果冻| 亚洲AV成人一区二区电影在线| 国产成人久久精品二区三区小说| 日韩一区二区三区AV| ZOOM与人性ZOOM视频| 欧美丰满美乳XXⅩ高潮WWW| 中文亚洲AV片在线观看无码 | 色欲av夜夜嗨av性色av| 草草影院CCYY国产日本欧美| 欧美最猛黑人XXXX黑人猛交 | 屁屁草草影院CCYYCOM| AV无码不卡在线观看免费| 年轻 娇小 亚洲人 日本语 夹| 中文字幕夫の上司に犯新沢平兰| 久久先锋男人AV资源网站| 亚洲中文字幕精品久久久久久动漫| 精品人妻系列无码专区| 亚洲国产精品久久久就秋霞| 黑人粗大与亚裔乱P视频| 亚洲成A人片在线观看你懂的| 狠狠色噜噜狠狠狠狠蜜桃| 亚洲AV无码国产精品久久不卡| 国产真实自在自偷| 亚洲AV理论在线电影网| 国内情侣作爱视频网站| 亚洲风情亚Aⅴ在线发布| 精品人妻无码视频一区二区三区| 亚洲精品无码久久久久Y| 精品水蜜桃久久久久久久| 亚洲一区二区三区乱码AⅤ蜜桃女| 久久精品熟女亚州AV麻豆| 亚洲资源AV无码日韩AV无码| 久久综合给合久久狠狠狠97色6 | 免费人成年激情视频在线观看| 18禁亲胸揉胸膜下刺激免费网站| 民工把我奶头掏出来了怎么办| 6080电影网站| 全免费A敌肛交毛片免费| 吃奶呻吟打开双腿做受是免费视频| 日韩午夜无码精品试看| 国产GV无码永久精品同性男男| 无码一区二区三区| 机长脔到她哭H粗话H动漫| 亚洲色AV无码AV丰满AV| 乱码AV麻豆丝袜熟女系列| 99国产欧美另娄久久久精品| 人人妻人人澡人人爽人人蜜臀| 饭桌上故意张开腿让公在线看 | 坐在根茎写作业好吗| 人妻AV中文系列| 国产SUV精品一区二区五| 亚洲AⅤ无码专区在线观看Q | 夜里18款禁用软件APP| 女人被狂躁的高潮免费视频| WW欧日韩视频高清在线| 射精专区一区二区朝鲜| 国模生殖欣赏337METCN| 野花香HD免费高清版6高清版| 女人和拘做受全过程免费| 厨房丝袜麻麻被后进怀孕| 午夜亚洲AV永久无码精品| 久久精品国产清自在天天线| 97国产精华最好的产品有哪些| 日韩乱码人妻无码超清蜜桃丨| 国产啪亚洲国产精品无码| 一二三四视频社区在线| 人妻少妇中文字幕乱码| 国产精品久久久久久无码| 亚洲人成人无码.WWW石榴| 欧美成人片一区二区三区| 国产97色在线 | 日| 亚洲女人操BB在线| 欧美 丝袜 自拍 制服 另类| 国99精品无码一区二区三区| 亚洲国产无套无码AV电影| 女口述第一次放进去的感受| 高潮到不停喷水的免费视频| 亚洲精品AⅤ中文字幕乱码| 欧美VA久久久噜噜噜久久| 丰满乳乱亲伦小说| 亚洲日韩一区二区三区| 人妻丝袜AV先锋影音先| 国内精品久久久久久无码不卡| 中文字幕亚洲无线码在线一区| 他的舌头含有起了我的小豆豆| 久久电影网午夜鲁丝片伦| А√天堂中文在线资源BT在线| 性少妇VIDEOXXX欧美69| 免费中文熟妇在线影片密芽| 国产精品高潮呻吟AV久久无码| 影音先锋日日狠狠久久| 视频视频APP在线看| 久久天堂综合亚洲伊人HD妓女| 大色堂午夜福利国产TV6080 |