昨天小組一成員跟一個萌新JAVA後端對接時,後端不會構建樹結構數據,要前端本身轉換,兩我的扯了半天,看不下去,寫了一個公共的方法來將有父子關係的數組轉換成樹形結構數據。前端
[
{
id: 1,
name: "1"
},
{
id: 2,
name: "1-1",
pid: 1
},
{
id: 3,
name: "1-1-1",
pid: 2
},
{
id: 4,
name: "1-2",
pid: 1
},
{
id: 5,
name: "1-2-2",
pid: 4
},
{
id: 6,
name: "1-1-1-1",
pid: 3
},
{
id: 7,
name: "2"
}
]
複製代碼
項目是用Vue開發,因此把方法添加到Vue的實例方法中後端
const install = function (Vue, opts) {
/**
* [deepClone 數組/對象深度拷貝]
* @param {[type]} source [數組/對象]
* @return {[type]} [description]
*/
Vue.prototype.deepClone = function (source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'shallowClone');
}
const targetObj = source.constructor === Array ? [] : {};
for (const keys in source) {
if (source.hasOwnProperty(keys)) {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = this.deepClone(source[keys]);
} else {
targetObj[keys] = source[keys];
}
}
}
return targetObj;
};
/**
* [structureTreeData 構建一個樹形結構數據]
* @param {[Array]} data [有父子關係的數組]
* @param {[String]} id [節點ID]
* @param {[String]} pid [對應父節點ID]
* @return {[Object]} [樹形結構數據]
*/
Vue.prototype.structureTreeData = function (data, id = "id", pid = "pid") {
//沒有父節點的數據
let parents = data.filter(
value => value.pid == "undefined" || value.pid == null
);
//有父節點的數據
let childrens = data.filter(
value => value.pid !== "undefined" && value.pid != null
);
//構造樹形結構數據
let structure = (parents, children) => {
//遍歷父節點數據
parents.forEach(parent => {
//遍歷子節點數據
childrens.forEach((children, index) => {
//此時找到父節點對應的一個子節點
if (children.pid === parent.id) {
//對子節點數據進行深拷貝
let newChildrens = this.deepClone(childrens);
//讓當前子節點從newChildrens中移除,newChildrens做爲新的子節點數據,
//這裏是爲了讓遞歸時,子節點的遍歷次數更少,若是父子關係的層級越多,越有利
newChildrens.splice(index, 1);
//讓當前子節點做爲惟一的父節點,去遞歸查找其對應的子節點
structure([children], newChildrens);
//把找到子節點放入父節點的children屬性中
typeof parent.children !== "undefined"
? parent.children.push(children)
: (parent.children = [children]);
}
});
});
};
//調用構造方法
structure(parents, childrens);
return parents;
};
}
export default {
install
}
複製代碼