import type { ViewProps } from '@tarojs/components'; import { classNames, isNullish } from 'mixlea-utils-js'; function composeEventHandler(handler1: (...args: any) => any, handler2: (...args: any) => any) { return (...args: any) => { // 先执行原有的事件回调函数 handler1(args); handler2(args); // 事件回调函数没有返回值,故这里不进行 return }; } /** 合并两个 cellProps(单元格属性)对象,返回一个合并后的全新对象。 * * mergeElementProps 会按照以下规则来合并两个对象: * * 对于 数字、字符串、布尔值类型的字段,extra 中的字段值将直接覆盖 base 中的字段值(className 是个特例,会进行字符串拼接) * * 对于函数/方法类型的字段(对应单元格的事件回调函数),mergeCellProps 将生成一个新的函数,新函数将按序调用 base 和 extra 中的方法 * * 对于普通对象类型的字段(对应单元格的样式),mergeCellProps 将合并两个对象 * */ export function mergeElementProps(base: T, extra: T) { if (isNullish(base)) { return extra; } if (isNullish(extra)) { return base; } const result: T = { ...base }; // eslint-disable-next-line no-restricted-syntax for (const key of Object.keys(extra)) { const value = (extra as any)[key]; const valueType = typeof value; if (value === null) { // value=null 时 覆盖原来的值 result[key as keyof ViewProps] = null; } else if (value === undefined) { // value=undefined 时 保留原来的值 } else if (['number', 'string', 'boolean'].includes(valueType)) { if (key === 'class') { result[key as keyof ViewProps] = classNames(result[key as keyof ViewProps], value); } else { result[key as keyof ViewProps] = value; } } else if (valueType === 'function') { const prev = result[key as keyof ViewProps]; if (isNullish(prev)) { result[key as keyof ViewProps] = value; } else { result[key as keyof ViewProps] = composeEventHandler(prev, value); } } else if (valueType === 'object') { result[key as keyof ViewProps] = { ...result[key as keyof ViewProps], ...value }; } // else `valueType` is 'bigint' or 'symbol', `value` is an invalid cellProp, ignore it } return result; }