iView Cascader舵揭、Tree 數(shù)據(jù)處理

iView 有個 Cascader防楷、Tree 組件如筛,數(shù)據(jù)要求比較嚴格(簡直弱爆了好嗎...)

問題簡述

Cascader 數(shù)據(jù)要求一覽(Tree 其實類似):

{
    value: 'jiangsu',
    label: '江蘇',
    children: [
        {
            value: 'nanjing',
            label: '南京',
            children: [
                {
                    value: 'fuzimiao',
                    label: '夫子廟',
                }
            ]
        }, {
            value: 'suzhou',
            label: '蘇州',
            children: [
                {
                    value: 'zhuozhengyuan',
                    label: '拙政園',
                }, {
                    value: 'shizilin',
                    label: '獅子林',
                }
            ]
        }
    ]
}

即:

  • value
  • label
  • children [可選]

發(fā)個牢騷

呃堡牡,誰的數(shù)據(jù)結構默認會是這樣的?肯定很少杨刨,幾乎沒有....不服咬我


話說就不能通過傳遞 value晤柄、labelchildren 的鍵值映射就配置 OK 了嗎妖胀,非得每個使用的地方轉一遍數(shù)據(jù)芥颈,累...就沒愛過

數(shù)據(jù)遞歸處理

好吧,做完一個項目了赚抡,稍微整理整理...


總得來說爬坑,這種數(shù)據(jù)還是比較好處理的。既然是樹結構涂臣,其實和 Cascader 組件所要求的數(shù)據(jù)格式基本類似盾计,無非字段名稱不一樣,字段可能更多而已肉康。

比如項目中某個需要展示部分數(shù)據(jù):

[
    {
        "department_id": 1,
        "department_name": "Test",
        "super_department_id": "0",
        "child_departments": [
            {
                "department_id": "34",
                "department_name": "修圖",
                "super_department_id": "1",
                "child_departments": []
            },
            {
                "department_id": "35",
                "department_name": "系統(tǒng)研發(fā)",
                "super_department_id": "1",
                "child_departments": [
                    {
                        "department_id": "48",
                        "department_name": "測試組",
                        "super_department_id": "35",
                        "child_departments": []
                    },
                    {
                        "department_id": "49",
                        "department_name": "產品組",
                        "super_department_id": "35",
                        "child_departments": []
                    },
                    {
                        "department_id": "50",
                        "department_name": "運營",
                        "super_department_id": "35",
                        "child_departments": []
                    },
                    {
                        "department_id": "51",
                        "department_name": "技術開發(fā)組",
                        "super_department_id": "35",
                        "child_departments": []
                    }
                ]
            }
        ]
    }
]

那么需要做的轉換如下:

  • department_id -> value
  • department_name -> label
  • children -> child_departments

這個做個簡單的遞歸就解決了闯估,代碼、注釋如下:

/**
 * tree 數(shù)據(jù)轉換
 * @param  {Array} tree 待轉換的 tree
 * @return {Array}      轉換后的 tree
 */
function convertTree (tree) {
    const result = []

    // 遍歷 tree
    tree.forEach((item) => {
        // 解構賦值
        let {
            department_id: value,
            department_name: label,
            child_departments: children
        } = item

        // 如果有子節(jié)點吼和,遞歸
        if (children) {
            children = convertTree(children)
        }

        result.push({
            value,
            label,
            children
        })
    })

    return result
}

最終得到數(shù)據(jù)如下:

[
    {
        "value": 1,
        "label": "Test",
        "children": [
            {
                "value": "34",
                "label": "修圖",
                "children": []
            },
            {
                "value": "35",
                "label": "系統(tǒng)研發(fā)",
                "children": [
                    {
                        "value": "48",
                        "label": "測試組",
                        "children": []
                    },
                    {
                        "value": "49",
                        "label": "產品組",
                        "children": []
                    },
                    {
                        "value": "50",
                        "label": "運營",
                        "children": []
                    },
                    {
                        "value": "51",
                        "label": "技術開發(fā)組",
                        "children": []
                    }
                ]
            }
        ]
    }
]

在線演示地址:https://jsfiddle.net/Roam/5xxcjfk8/

貌似結束了

其實好像也就那么回事涨薪,十來行代碼就敲定了。
但是炫乓,回頭一想刚夺,也不對,每種數(shù)據(jù)都要寫個轉換末捣,也是神煩 = =
好吧侠姑,繼續(xù)優(yōu)化優(yōu)化吧...

其實可以把遞歸函數(shù)再改改:

/**
 * tree 數(shù)據(jù)轉換
 * @param  {Array} tree 待轉換的 tree
 * @param  {Object} map  鍵值對映射
 * @return {Array}      轉換后的 tree
 */
function convertTree (tree, map) {
    const result = []

    // 遍歷 tree
    tree.forEach((item) => {
        // 讀取 map 的鍵值映射
        const value = item[ map.value ]
        const label = item[ map.label ]
        let children = item[ map.children ]

        // 如果有子節(jié)點,遞歸
        if (children) {
            children = convertTree(children, map)
        }

        result.push({
            value,
            label,
            children
        })
    })

    return result
}

就是增加了一個 map 參數(shù)箩做,用于指定 value莽红、labelchildren 的字段映射:

{
    value: 'department_id',
    label: 'department_name',
    children: 'child_departments'
}

這樣這個遞歸方法就可以抽出來了邦邦,需要轉換的地方安吁,調這個方法就行了
感覺可以提個 feature

再來個復雜點的數(shù)據(jù)處理

在做部門展示權限的時候,遇到個問題燃辖,簡化如下:

  • 如果一個節(jié)點有權限鬼店,那么顯示該節(jié)點,且顯示所屬的父節(jié)點
  • 如果該節(jié)點有權限黔龟,且該節(jié)點有子節(jié)點妇智,子節(jié)點全部顯示

用圖描述一下好了:

selected-tree.png
  • A 為 root 節(jié)點
  • 綠色表示有權限

需要將上面的轉換得到如下 tree 結構:

filtered-tree.png

用數(shù)據(jù)來說話就是:

 [
    {
        "name": "A",
        "children": [
            {
                "name": "B",
            }, {
                "name": "C",
                "children": [
                    {
                        "name": "E",
                        "visible": true
                    }, {
                        "name": "F"
                    }
                ]
            }, {
                "name": "D",
                "visible": true,
                "children": [
                    {
                        "name": "G"
                    }, {
                        "name": "H"
                    }, {
                        "name": "I"
                    }
                ]
            }
        ]
    }
]

轉成:

[
    {
        "name": "A",
        "children": [
            {
                "name": "C",
                "children": [
                    {
                        "name": "E",
                        "visible": true
                    }
                ]
            }, {
                "name": "D",
                "visible": true,
                "children": [
                    {
                        "name": "G"
                    }, {
                        "name": "H"
                    }, {
                        "name": "I"
                    }
                ]
            }
        ]
    }
]

初看一臉懵逼
再看還是一臉懵逼....


細細捋一捋...

  • 遍歷樹
  • 如果當前節(jié)點有權限滥玷,塞進來
  • 如果當前節(jié)點無權限,并且無子節(jié)點巍棱,拋棄
  • 如果當前節(jié)點無權限惑畴,遍歷子節(jié)點(重復如上)

嗯~ o( ̄▽ ̄)o,就是這樣的...

這里有個技巧拉盾,就是使用 Array.prototype.filter()

 // 原始數(shù)據(jù)
 const raw = [
    {
        "name": "A",
        "children": [
            {
                "name": "B",
            }, {
                "name": "C",
                "children": [
                    {
                        "name": "E",
                        "visible": true
                    }, {
                        "name": "F"
                    }
                ]
            }, {
                "name": "D",
                "visible": true,
                "children": [
                    {
                        "name": "G"
                    }, {
                        "name": "H"
                    }, {
                        "name": "I"
                    }
                ]
            }
        ]
    }
]

/**
 * Tree 過濾
 * @param  {Array} tree 待過濾的 tree
 * @return {Array}      已過濾的 tree
 */
function filterTree (tree) {
    let result = []

    // filter 遍歷
    result = tree.filter((item) => {
        // 如果有權限
        if (item.visible) {
            return true

        // 如果有子節(jié)點桨菜,遞歸子節(jié)點
        // 如果有權限豁状,返回的值應該為非空數(shù)組
        } else if (item.children && item.children.length > 0) {
            item.children = filterTree(item.children)

            return item.children.length > 0

        // 拋棄
        } else {
            return false
        }
    })

    return result
}

console.log( JSON.stringify(filterTree(raw), null, 4) )

// 打印結果
// [
//     {
//         "name": "A",
//         "children": [
//             {
//                 "name": "C",
//                 "children": [
//                     {
//                         "name": "E",
//                         "visible": true
//                     }
//                 ]
//             },
//             {
//                 "name": "D",
//                 "visible": true,
//                 "children": [
//                     {
//                         "name": "G"
//                     },
//                     {
//                         "name": "H"
//                     },
//                     {
//                         "name": "I"
//                     }
//                 ]
//             }
//         ]
//     }
// ]

其實也就十來行...

在線演示鏈接:https://jsfiddle.net/Roam/5jb0r8y5/

tree.gif

總結

  • 遞歸是個好東西捉偏,能省很多代碼(讓我想起一個面試題...淡淡的憂傷)
  • 代碼寫得不順手,肯定哪里有問題
  • 知乎上前后端就是倆冤家

今年本來打算告別后臺管理開發(fā)泻红,找個移動開發(fā)的工作
不想局限于 PC夭禽,不想成為一個擰螺絲的,不想看見 IE6
無奈之前做的全是 PC 后臺管理項目谊路,沒有移動經(jīng)驗讹躯,逛了一圈又回去了

如果只局限于當前的工作內容,也就那樣了缠劝,以后也就真的那樣了

啊潮梯,Hexo 皮膚還沒寫完啊,許久沒動了....


少年...

—— 2018/05/29 By Live惨恭, Haze.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末秉馏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子脱羡,更是在濱河造成了極大的恐慌萝究,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锉罐,死亡現(xiàn)場離奇詭異帆竹,居然都是意外死亡,警方通過查閱死者的電腦和手機脓规,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門栽连,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侨舆,你說我怎么就攤上這事秒紧。” “怎么了态罪?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵噩茄,是天一觀的道長。 經(jīng)常有香客問我复颈,道長绩聘,這世上最難降的妖魔是什么沥割? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮凿菩,結果婚禮上机杜,老公的妹妹穿的比我還像新娘。我一直安慰自己衅谷,他們只是感情好椒拗,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著获黔,像睡著了一般蚀苛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玷氏,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天堵未,我揣著相機與錄音,去河邊找鬼盏触。 笑死渗蟹,一個胖子當著我的面吹牛,可吹牛的內容都是我干的赞辩。 我是一名探鬼主播雌芽,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辨嗽!你這毒婦竟也來了世落?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤召庞,失蹤者是張志新(化名)和其女友劉穎岛心,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篮灼,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡忘古,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诅诱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片髓堪。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娘荡,靈堂內的尸體忽然破棺而出干旁,到底是詐尸還是另有隱情,我是刑警寧澤炮沐,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布争群,位于F島的核電站,受9級特大地震影響大年,放射性物質發(fā)生泄漏换薄。R本人自食惡果不足惜玉雾,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轻要。 院中可真熱鬧复旬,春花似錦、人聲如沸冲泥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凡恍。三九已至志秃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咳焚,已是汗流浹背洽损。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工庞溜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留革半,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓流码,卻偏偏與公主長得像又官,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子漫试,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經(jīng)驗六敬。 張土汪:刷leetcod...
    土汪閱讀 12,738評論 0 33
  • 題量有點多,建議Ctrl + F題號或題目哦~ 二叉樹的遍歷(前序遍歷驾荣,中序遍歷外构,后序遍歷)[144] Binar...
    野狗子嗷嗷嗷閱讀 9,085評論 2 37
  • 廢話不多說,亮代碼播掷。python執(zhí)行 耗時:0.011912sPHP執(zhí)行 耗時:0.002054s結論:PHP效率...
    xhat閱讀 5,472評論 3 1
  • 開學以后的每一個月都好長歧匈,回頭看的時候會發(fā)現(xiàn)很多新鮮的情緒垒酬,比如思念,比如心疼件炉,比如感動… 四月一日的時候和阿熙特...
    人間甜妞兒閱讀 344評論 0 1
  • 好多天沒有寫日記了憔鬼,以至于我連日期都記的不是很好陨晶。 這段時間也算不上有多努力,而日子就這么一天天過去了。我現(xiàn)在正在...
    muziyue閱讀 183評論 0 1