使用 export 语法将工具函数暴露出去
/** * @function 生成UUID * @export 导出为工具函数 * @return {String} 返回值为生成的UUID */export const generateUUID = () => { let date = new Date().getTime(); let uuid = "xxxx_xxxx_xxxx_yxxx".replace(/[xy]/g, function (char) { let random = (date + Math.random() * 16) % 16 | 0; date = Math.floor(date / 16); return (char == "x" ? random : (random & 0x7) | 0x8).toString(16); }); return uuid;};
/** * @function 深拷贝对象 * @export 导出为工具函数 * @param {Object|Array} 入参为被拷贝对象或数组 * @return {Object|Array} 返回值为拷贝出的对象或数组 */export const deepCopyObject = (obj) => { let newObj; Array.isArray(obj) ? (newObj = []) : (newObj = {}); const keyArray = Object.keys(obj); keyArray.forEach((key) => { if (typeof obj[key] == "object" && obj[key] != null) { newObj[key] = deepCopyObject(obj[key]); } else { newObj[key] = obj[key]; } }); return newObj;};
/** * @function 根据id和parentId生成树 * @export 导出为工具函数 * @param {Object} 所有参数都在对象中 * @param {Array} [data=[]] 生成树的原始一维数组,默认为[] * @param {String|Number} [rootId = 0] 根节点id,默认为0 * @param {String} [id="id"] id字段名,默认为"id" * @param {String} [parentId="parentId"] parentId字段名,默认为"parentId" * @param {String} [children="children"] children字段名,默认为"children" * @return {Array} 返回生成树的数组 */export const createTree = ({ data = [], rootId = 0, id = "id", parentId = "parentId", children = "children" } = {}) => { // 过滤遍历树原始数组,当前遍历项为父节点,返回根节点数组 return data.filter((parent) => { parent.expand = true; // 嵌套过滤遍历树原始数组,当前遍历项为子节点,返回当前父节点的所有子节点 let branchArr = data.filter((child) => { return parent[id] == child[parentId]; }); if (branchArr.length > 0) { // 若存在子节点,则给父节点添加一个children属性,并将branchArr赋值给父节点 parent[children] = branchArr; } return parent[parentId] == rootId; //返回根节点数组 });};/** * 通过id与parentId的一维数组生成树(Typescript) * 该方法相较上面的filter递归方式执行效率更高,时间复杂度由O(n2)降低为O(n) * @param 配置对象 data为原始数据;rootId为根节点对应的id值;idAttr为id字段名,默认为id;parentAttr为父id字段名,默认为parentId;childrenAttr为子节点字段名,默认为children * @returns 树数组 */export const createTree = ({ data = [], rootId = 0, idAttr = "id", parentAttr = "parentId", childrenAttr = "children",}: { data: { [key: string]: any }[], rootId?: number, idAttr?: string, parentAttr?: string, childrenAttr?: string,}) => { // 生成用于查找父节点的map const map = data.reduce((map, item, index) => { map[item[idAttr]] = index; item[childrenAttr] = []; return map; }, {}); // 将每个元素挂载到对应的父节点 return data.reduce((tree, item, index, arr) => { // 若当前节点的父节点为根节点,则放入最终的树数组 if (item[parentAttr] === rootId) tree.push(item); // 否则将当前节点挂载到相应的父节点上 else { // 判断父节点是否存在于map中,存在则挂载,否则报错 if (map[item[parentAttr]] !== undefined) arr[map[item[parentAttr]]][childrenAttr].push(item); else console.error(`Id ${item[idAttr]} No Parent Found`); } return tree; }, []);};
/** * @function iview手风琴树(每次只展开一个树节点) * @export 导出为工具函数 * @param {Object} 入参1:当前节点对象 * @param {Array} 入参2:树的数组数据 */export const accordionTree = (currentNode, treeData) => { /** * @function 查找当前节点父节点 * @param {Array} 入参1:树的数组数据 * @param {Object} 入参2: 当前节点对象 * @return {Object} 返回值为当前节点的父节点对象 */ function findParent(treeData, currentNode) { // 声明最终父节点 let finalParentNode = null; /** * @function 查找当前节点父节点的内部递归函数 * @param {Array} 入参1:树的数组数据 * @param {Object} 入参2:当前点击节点对象 * @param {Object} 入参3:此时遍历节点的父节点 */ function findParentInner(treeData, currentNode, parentNode) { // 内部查找函数,若当前节点nodeKey与遍历节点nodeKey相同时,则此时的parentNode为要找的最终父节点,否则判断遍历节点是否存在子节点,若存在则递归执行函数,若不存在则什么都不做 treeData.forEach((item) => item.nodeKey === currentNode.nodeKey ? (() => { finalParentNode = parentNode; })() : (() => { item.children ? findParentInner(item.children, currentNode, item) : ""; })() ); } // 执行内部函数 findParentInner(treeData, currentNode, finalParentNode); return finalParentNode; } /** * @function 折叠树其它节点 * @param {Array} 入参1:树的数组数据 * @param {Object} 入参2:当前点击节点对象 */ function collapseTree(treeData, currentNode) { treeData.forEach((item) => { // 若遍历节点为折叠则什么都不做,若为展开则判断遍历节点与当前节点nodeKey是否相同,若相同则什么都不做,否则设为折叠 item.expand ? (() => { item.nodeKey === currentNode.nodeKey ? "" : (item.expand = false); })() : (() => {})(); // 若遍历节点存在子节点则递归此函数,否则什么都不做 item.children ? collapseTree(item.children, currentNode) : ""; }); } // 找到当前点击节点的父节点 let parentNode = findParent(treeData, currentNode); // 折叠树,若父节点为null,则为根节点,传入所有树数据(根节点);若不为null,则传入父节点的子节点 parentNode === null ? collapseTree(treeData, currentNode) : collapseTree(parentNode.children, currentNode);};参考资料 生成树方法 createTree