/** * * @param newTree Arr * @param oldTree Arr * @param cb Fun (newItem, oldItem, parents) => {} newItem: newTree 的 item. oldItem oldTree 的 item,可能会不存在. parents newItem 的 父级, 可能会不存在 * @param conf { idKey: string, childrenKey: string } */ function contrastTree(newTree, oldTree, cb, conf = {idKey:'id', childrenKey: 'children'}) { if (!newTree || !newTree) { console.warn('contrastTree: newTree 和 oldTree 必须存在') return } if (!Array.isArray(newTree) || !Array.isArray(oldTree)) { console.warn('contrastTree: newTree 和 oldTree 必须为数组') return } if (Object.prototype.toString.apply(conf) !== '[object Object]') { console.warn('conf 必须为 Object') return } // 遍历树 function deepEach(tree, callback, parents) { tree.forEach(item => { const Children = item[conf.childrenKey] const HaveChildren = Children && Array.isArray(Children) // 传入父级 callback(item, parents) if (HaveChildren) { deepEach(Children, callback, item) } }) } // 拉平 OldTreeArr,将arr 转为 obj格式,方便取值 const OldTreeObj = {} deepEach(oldTree, (item) => { OldTreeObj[item[conf.idKey]] = item }) // 开始双树对比 deepEach(newTree, (newItem, parents) => { const OldItem = OldTreeObj[newItem[conf.idKey]] cb(newItem, OldItem, parents) }) }