實(shí)現(xiàn)一個(gè)可無(wú)限折疊的table

http://www.reibang.com/p/47951125d15b


如何在table上實(shí)現(xiàn)一個(gè)可折疊展開(kāi)子節(jié)點(diǎn)的table?先看下最終實(shí)現(xiàn)效果圖:

項(xiàng)目地址:源碼傳送門(mén)

demodemo傳送門(mén)

技術(shù)棧:

vue

javascript

動(dòng)手實(shí)現(xiàn)

為有興趣的同學(xué)先準(zhǔn)備一下大綱目錄預(yù)覽,為了不讓同學(xué)們看入迷似踱,讓大綱為你指明前行的道路帮掉!

大綱預(yù)覽

明確需求

樹(shù)形結(jié)構(gòu)數(shù)據(jù)準(zhǔn)備

數(shù)據(jù)扁平化(重點(diǎn))

層級(jí)展示

折疊展開(kāi)功能實(shí)現(xiàn)

1. 明確需求

實(shí)現(xiàn)一個(gè)可折疊展開(kāi)的table单匣,看上去很迷茫的樣子团南。但實(shí)際上就是:

table上點(diǎn)擊時(shí)對(duì)其子集進(jìn)行隱藏顯示

通過(guò)縮進(jìn)的距離來(lái)表現(xiàn)層級(jí)關(guān)系

在代碼里很東西其實(shí)都是偽裝出來(lái)的宗雇,例如我們要實(shí)現(xiàn)的這個(gè)可無(wú)限折疊的table钳恕。但在用戶操作的時(shí)候看來(lái)就是那么回事咯 ~ ~

2. 樹(shù)形結(jié)構(gòu)數(shù)據(jù)準(zhǔn)備

這里已經(jīng)準(zhǔn)備好了樹(shù)形結(jié)構(gòu)的數(shù)據(jù)别伏,存放于data.js的文件中,節(jié)點(diǎn)通過(guò)Children連接忧额。如標(biāo)題所說(shuō)厘肮,可無(wú)限折疊,無(wú)論這里的樹(shù)形數(shù)據(jù)有多少層級(jí)睦番,都能給它辦妥當(dāng)了类茂。先把牛吹在這,接下來(lái)看看如何實(shí)現(xiàn)托嚣。

3. 數(shù)據(jù)扁平化

條件梳理

樹(shù)形結(jié)構(gòu)數(shù)據(jù)扁平化并不難巩检,難點(diǎn)在于在扁平化的時(shí)候要做的處理。這里深入梳理一下:

我們將一個(gè)樹(shù)節(jié)點(diǎn)的所有父節(jié)點(diǎn)稱為family示启,好比我們要知道的自己的大領(lǐng)導(dǎo)兢哭、二領(lǐng)導(dǎo)、直系領(lǐng)導(dǎo)...因?yàn)樗麄兊拿钤蹅兌嫉脠?zhí)行夫嗓。在這個(gè)表單中就是當(dāng)父節(jié)點(diǎn)或更高的祖輩節(jié)點(diǎn)發(fā)命令時(shí)迟螺,做一個(gè)懂事的子節(jié)點(diǎn)當(dāng)然要聽(tīng)話辦事冲秽。__family字段就是用來(lái)存放所有所有的父節(jié)點(diǎn)的數(shù)組。在扁平化數(shù)據(jù)是通過(guò)數(shù)組字段__family收集其所有父節(jié)點(diǎn)煮仇。這樣一來(lái)劳跃,就像族譜一樣,就能清晰知道該節(jié)點(diǎn)的所有父節(jié)點(diǎn)浙垫。 至于如和折疊收縮呢刨仑? **我們通過(guò)一個(gè)foldList數(shù)組來(lái)記錄要 **折疊的節(jié)點(diǎn) ,也稱為死亡名單夹姥。如此一來(lái)杉武,只要包含父節(jié)點(diǎn)標(biāo)識(shí)節(jié)點(diǎn)就乖乖的隱藏吧。

每個(gè)成員都因該是唯一的辙售,那么我們?cè)诒闅v時(shí)都應(yīng)該為每個(gè)成員添加一個(gè)唯一標(biāo)識(shí)__identity轻抱。正是上一個(gè)步驟中說(shuō)的節(jié)點(diǎn)標(biāo)志

為了明確知道各個(gè)節(jié)點(diǎn)之間的層級(jí)關(guān)系旦部,通過(guò)__level明確層級(jí)關(guān)系祈搜。那么我們規(guī)定__level的值越小等級(jí)越高。__level=0代表首層節(jié)點(diǎn)士八。

既然是無(wú)限層級(jí)姚糊,肯定是用遞歸來(lái)實(shí)現(xiàn)了句喷。formatConversion()方法實(shí)現(xiàn)遞歸。那何時(shí)跳出當(dāng)前遍歷的遞歸呢?當(dāng)前節(jié)點(diǎn)沒(méi)有子集時(shí)Children.length = 0的時(shí)候跳出本次遞歸嘴拢,進(jìn)行下一次遞歸家乘。該方法可能需要花點(diǎn)時(shí)間理解娜汁,代碼里注釋已寫(xiě)的比較詳細(xì)党晋,有問(wèn)題歡迎留言溝通~~

數(shù)據(jù)扁平化

/*********************************

** Fn: formatConversion

** Intro: 將樹(shù)形接口數(shù)據(jù)扁平化

** @params: parent 為當(dāng)前累計(jì)的數(shù)組? 也是最后返回的數(shù)組

** @params: children 為當(dāng)前節(jié)點(diǎn)仍需繼續(xù)扁平子節(jié)點(diǎn)的數(shù)據(jù)

** @params: index 默認(rèn)等于0, 用于在遞歸中進(jìn)行累計(jì)疊加 用于層級(jí)標(biāo)識(shí)

** @params: family 裝有當(dāng)前包含元素自身的所有父級(jí) 身份標(biāo)識(shí)

** @params: elderIdentity 父級(jí)的? 唯一身份標(biāo)識(shí)

** Author: zyx

*********************************/formatConversion(parent,children,index=0,family=[],elderIdentity='x'){// children如果長(zhǎng)度等于0哮翘,則代表已經(jīng)到了最低層// let page = (this.startPage - 1) * 10if(children.length>0){children.map((x,i)=>{// 設(shè)置 __level 標(biāo)志位 用于展示區(qū)分層級(jí)Vue.set(x,'__level',index)// 設(shè)置 __family 為家族關(guān)系 為所有父級(jí)颈嚼,包含本身在內(nèi)Vue.set(x,'__family',[...family,elderIdentity+'_'+i])// 本身的唯一標(biāo)識(shí)? 可以理解為個(gè)人的身份證咯 一定唯一。Vue.set(x,'__identity',elderIdentity+'_'+i)parent.push(x)// 如果仍有子集饭寺,則進(jìn)行遞歸if(x.Children.length>0)this.formatConversion(parent,x.Children,index+1,[...family,elderIdentity+'_'+i],elderIdentity+'_'+i)})}returnparent}

我們來(lái)對(duì)比一下扁平話的數(shù)據(jù)

原數(shù)據(jù)

扁平化后的數(shù)據(jù)

對(duì)比數(shù)據(jù)的前后阻课,先明確(父節(jié)點(diǎn):Name: "App"), (子節(jié)點(diǎn):Name: "企業(yè)查詢")。我們先看看__level字段佩研,分別對(duì)應(yīng)0和1柑肴,沒(méi)問(wèn)題霞揉。__family包含了本身節(jié)點(diǎn)旬薯。__identity的個(gè)格式就是前綴 x加上在數(shù)據(jù)中的位置。例如節(jié)點(diǎn)App在數(shù)據(jù)中的位置是第一個(gè)節(jié)點(diǎn)适秩,那對(duì)應(yīng)的__identity即是x_0绊序。企業(yè)查詢位于App節(jié)點(diǎn)下的第一個(gè)元素硕舆,則在父節(jié)點(diǎn)的標(biāo)識(shí)的基礎(chǔ)上追加一位0,那對(duì)應(yīng)的__identity即是x_0_0骤公。其他依次類(lèi)推抚官。一切已準(zhǔn)備妥當(dāng)~~

4. 層級(jí)展示

如圖所示:

如果展示層級(jí)呢?利用css即可實(shí)現(xiàn)

字體圖標(biāo)準(zhǔn)備: 這里先補(bǔ)充一點(diǎn)阶捆,這里涉及兩個(gè)字體圖標(biāo)凌节,圖中紅色框標(biāo)注的,資源存放于src目錄下的iconfont目錄下中洒试。層級(jí)最低的字段時(shí)不需要展示該圖標(biāo)呢倍奢,該如何判斷呢?通過(guò)判斷當(dāng)前節(jié)點(diǎn)是否還有子集params.Children.length === 0即可判斷垒棋。若沒(méi)有子集則不設(shè)置字體圖標(biāo)即可卒煞。點(diǎn)擊時(shí)還需要對(duì)圖標(biāo)進(jìn)行切換,這又如何實(shí)現(xiàn)呢叼架?前臺(tái)提到過(guò)的死亡名單foldList畔裕,如果該存在該名單中,代表該數(shù)據(jù)已經(jīng)被折疊乖订,那返回折疊圖標(biāo)扮饶。否則返回展開(kāi)圖標(biāo)。如代碼:

//? ? html<i:class="toggleFoldingClass(scope.row)"></i>//? ? js methods:/*********************************

? ? ? ** Fn: toggleFoldingClass

? ? ? ** Intro: 如果子集長(zhǎng)度為0垢粮,則不返回字體圖標(biāo)贴届。

? ? ? ** Intro: 如果子集長(zhǎng)度為不為0,根據(jù)foldList是否存在當(dāng)前節(jié)點(diǎn)的標(biāo)識(shí)返回相應(yīng)的折疊或展開(kāi)圖標(biāo)

? ? ? ** Intro: 關(guān)于class說(shuō)明:permission_placeholder返回一個(gè)占位符蜡吧,具體查看class

? ? ? ** @params: params 當(dāng)前行的數(shù)據(jù)對(duì)象

? ? ? ** Author: zyx

? ? *********************************/toggleFoldingClass(params){returnparams.Children.length===0?'permission_placeholder':(this.foldList.indexOf(params.__identity)===-1?'iconfont icon-minus-square-o':'iconfont icon-plussquareo')},

層級(jí)展示:__level字段就是這時(shí)候發(fā)揮用處毫蚓。__level值越大,則將margin-left值增大昔善。如代碼:

<p:style="`margin-left: ${scope.row.__level * 20}px;`">...

基本的樣子已經(jīng)有了元潘,那接下來(lái)實(shí)現(xiàn)點(diǎn)擊功能。

5. 折疊展開(kāi)功能實(shí)現(xiàn)

記錄點(diǎn)擊的節(jié)點(diǎn)標(biāo)識(shí)

通過(guò)死亡名單foldList來(lái)記錄點(diǎn)擊君仆。點(diǎn)擊事件在點(diǎn)擊折疊展開(kāi)圖標(biāo)時(shí)觸發(fā)toggleFoldingStatus(scope.row)事件翩概,前面也說(shuō)過(guò),foldList存在的標(biāo)識(shí)返咱,對(duì)于所有的子節(jié)點(diǎn)都要隱藏起來(lái)钥庇。如果foldList沒(méi)有數(shù)據(jù),則全部展開(kāi)咖摹,萬(wàn)事大吉评姨。代碼如圖所示,就是那么簡(jiǎn)單萤晴。

//? ? html<i? @click="toggleFoldingStatus(scope.row)"class="permission_toggleFold":class="toggleFoldingClass(scope.row)"></i>//? ? js methods/*********************************

? ? ? ** Fn: toggleFoldingStatus

? ? ? ** Intro: 切換展開(kāi) 還是折疊

? ? ? ** @params: params 當(dāng)前點(diǎn)擊行的數(shù)據(jù)

? ? ? ** Author: zyx

? ? *********************************/toggleFoldingStatus(params){this.foldList.includes(params.__identity)?this.foldList.splice(this.foldList.indexOf(params.__identity),1):this.foldList.push(params.__identity)},

折疊展開(kāi)功能實(shí)現(xiàn)

萬(wàn)事俱備吐句,只欠東風(fēng)胁后。最后一件要做的大事就是根據(jù)死亡名單foldList來(lái)進(jìn)行顯示和隱藏?cái)?shù)據(jù)。 這里借助el-table中的row-style實(shí)現(xiàn)嗦枢。同學(xué)們也可以自己實(shí)現(xiàn)攀芯。來(lái)看下官方的說(shuō)明

![](http://upload-images.jianshu.io/upload_images/13661853-aeb3373889e7cc00.png!web?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

該方法就是為table中的每一行數(shù)據(jù)設(shè)置樣式。

/*********************************

** Fn: toggleDisplayTr

** Intro: 該方法會(huì)對(duì)每一行數(shù)據(jù)都做判斷 如果foldList 列表中的元素 也存在與當(dāng)前行的 __family列表中? 則該行不展示

** @params:

** Author: zyx

*********************************/toggleDisplayTr({row,index}){for(let i=0;i<this.foldList.length;i++){let item=this.foldList[i]// 如果foldList中元素存在于 row.__family中文虏,則該行隱藏侣诺。? 如果該行的自身標(biāo)識(shí)等于隱藏元素,則代表該元素就是折疊點(diǎn)if(row.__family.includes(item)&&row.__identity!==item)return'display:none;'}return''},

在來(lái)看看效果

錦上添花

如果數(shù)據(jù)太多的話氧秘,一個(gè)層級(jí)層級(jí)的去搜索確實(shí)也麻煩紧武,所以那么我們?cè)賮?lái)添加兩個(gè)按鈕全部折疊全部展開(kāi)好了。 咨詢分析一下敏储,其實(shí)這個(gè)功能很簡(jiǎn)單阻星。還是關(guān)于前面提到過(guò)的死亡名單foldList。

全部展開(kāi): 如果foldList為空已添,則萬(wàn)事大吉妥箕,數(shù)據(jù)全部展開(kāi)。

全部折疊:我們的設(shè)計(jì)是只要存在于死亡名單的所有包含該標(biāo)識(shí)的節(jié)點(diǎn)都要隱藏更舞。那么只要將所有的首層節(jié)點(diǎn)添加進(jìn)去就可以了畦幢。this.foldList = this.tableListData.map(x => x.__identity)即取出首層節(jié)點(diǎn)的標(biāo)識(shí)。

結(jié)語(yǔ)

更復(fù)雜的需求是結(jié)合分頁(yè)缆蝉,當(dāng)從其他頁(yè)回到之前頁(yè)時(shí)宇葱,之前頁(yè)的折疊狀態(tài)要依舊保持。這里就不在說(shuō)明了刊头,因?yàn)閼?yīng)用場(chǎng)景很少黍瞧。

點(diǎn)贊給個(gè)鼓勵(lì)喲~

文章出處:https://juejin.im/post/5be797456fb9a04a0378bb91。歡迎大家前去點(diǎn)贊支持~原杂!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末印颤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子穿肄,更是在濱河造成了極大的恐慌年局,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咸产,死亡現(xiàn)場(chǎng)離奇詭異矢否,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)脑溢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)僵朗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事衣迷。” “怎么了酱酬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵壶谒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我膳沽,道長(zhǎng)汗菜,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任挑社,我火速辦了婚禮陨界,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痛阻。我一直安慰自己菌瘪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布阱当。 她就那樣靜靜地躺著俏扩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弊添。 梳的紋絲不亂的頭發(fā)上录淡,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音油坝,去河邊找鬼嫉戚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛澈圈,可吹牛的內(nèi)容都是我干的彬檀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瞬女,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凤覆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拆魏,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盯桦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后渤刃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拥峦,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年卖子,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了略号。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖玄柠,靈堂內(nèi)的尸體忽然破棺而出突梦,到底是詐尸還是另有隱情,我是刑警寧澤羽利,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布宫患,位于F島的核電站,受9級(jí)特大地震影響这弧,放射性物質(zhì)發(fā)生泄漏娃闲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一匾浪、第九天 我趴在偏房一處隱蔽的房頂上張望皇帮。 院中可真熱鬧,春花似錦蛋辈、人聲如沸属拾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捌年。三九已至,卻和暖如春挂洛,著一層夾襖步出監(jiān)牢的瞬間礼预,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工虏劲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留托酸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓柒巫,卻偏偏與公主長(zhǎng)得像励堡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子堡掏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 如何在table上實(shí)現(xiàn)一個(gè)可折疊展開(kāi)子節(jié)點(diǎn)的table应结?先看下最終實(shí)現(xiàn)效果圖: 項(xiàng)目地址: : 源碼傳送門(mén) dem...
    老王420閱讀 5,527評(píng)論 0 68
  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,815評(píng)論 0 5
  • 程序設(shè)計(jì)中常使用樹(shù)型結(jié)構(gòu)來(lái)表征某些數(shù)據(jù)的關(guān)聯(lián)關(guān)系泉唁,如上下級(jí)鹅龄、欄目結(jié)構(gòu)、商品分類(lèi)亭畜、菜單扮休、回復(fù)等。 分類(lèi)的層級(jí)關(guān)系可以...
    JunChow520閱讀 4,087評(píng)論 4 3
  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵勝奧閱讀 4,764評(píng)論 0 1
  • 時(shí)光匆匆拴鸵,一眨眼玷坠,我們又快迎來(lái)2018年了蜗搔,但2017年的愿望你還記得嗎? 我感覺(jué)冬天就是一個(gè)蟄伏的季節(jié)八堡,就像農(nóng)民...
    特立獨(dú)行的茱閱讀 152評(píng)論 0 1