- 数组:
[
{
id: 1,
name: "1"
pid: 0,
},
{
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 pids = [];
let ids = [];
data.forEach(item => {
if (!pids.includes(item.pid)) {
pids.push(item.pid);
}
if (!ids.includes(item.id)) {
ids.push(item.id);
}
});
//父节点数据
let parents = data.filter(
value => !ids.includes(value.pid)
);
//子节点数据
let childrens = data.filter(
value => ids.includes(value.pid)
);
//构造树形结构数据
let structure = (parents, childrens) => {
//遍历父节点数据
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
}