UNPKG

cjd-parkball

Version:

> 中后台业务组件库,中后台就像公园,进入需要买门票(登录),所以以 Parkball(公园球) 命名,公园内必定捕获!作为一个组件库,提供使用方法文档,方便开发者的调用

156 lines (149 loc) 5.64 kB
// 检查render属性,作用是检查columns配置中是否含有render属性并进一步检查render是否 const haveProps = (items, proto) => { // 如果都没有render属性 const noneHasRender = items.every(item => !item.render) if (noneHasRender) return [] // 有render属性,那么其必定是个函数,运行每个函数,暂存每个结果并加以判断 const renderRes = items.map((item) => { if (typeof item.render === 'function') return item.render() return item }) // 检查每个render的函数结果是否含有props属性且props属性是否含有rowSpan以及colSpan // 每个render函数返回的都是ReactElement对象 const allOfThemAreReactElement = renderRes.every(item => item.$$typeof && item.$$typeof.toString() === 'Symbol(react.element)') if (allOfThemAreReactElement) return [] // 是否存在props属性 const defective = [] const noneHasProps = renderRes.every(item => !item.props) if (noneHasProps) return [] renderRes.forEach((item, index) => { // 判断object中是否存在proto // toString防止存在rowSpan或者colSpan为0的情况无法得到合并的dataIndex if (item.props && (typeof item.props[proto] === 'number')) { const dataIndex = items[index].key || items[index].dataIndex defective.push(dataIndex) } }) if (defective.length === 0) return [] return defective } // 输出两个数组之间的不同的值 /* eslint-disable */ const difference = (source, target) => { if (target.length === 0) return source let index = -1 const res = [] const targetLength = target.length outer: while (++index < source.length) { const value = source[index] let targetIndex = targetLength while (targetIndex --) { if (target[targetIndex] === value) continue outer res.push(value) } } return res } // 数组形式的collapseRow const getRowSpanDataByArray = (shouldRerender, dataSource) => { // 如果传入的配置单纯是数组的话,那么简单的按照传入的dataIndex来合并行 const rowSpanData = {} // 计数有几个相同的 let count = 1 let tempVal = undefined let index = -1 const dataIndexLength = shouldRerender.length /** * 得到如下的结构的数据 * { * key: { * start: 记录开始的index信息 * length: 同一个dataIndex的相同值的长度 * } * } */ while(++ index < dataIndexLength) { const _dataIndex = shouldRerender[index] let start = 0 dataSource.forEach((item, index) => { const current = item[_dataIndex] if (current !== tempVal) { if (!rowSpanData[current]) rowSpanData[current] = [] if (tempVal) rowSpanData[tempVal].push({ start, length: count }) start = index tempVal = current count = 1 return 0 } count ++ }) // 补全最后一个的长度信息 rowSpanData[tempVal].push({ start, length: count }) } return rowSpanData } function formatColumns (sourceColumns) { const { collapseRow, collapseCol, dataSource } = this.props // 如果不存在collapseRow或者collapseCol属性返回原始的sourceColumns配置 if (!(collapseRow || collapseCol)) return sourceColumns // console.log('[source columns]', sourceColumns) /** * collapseRow, collapseCol * 当参数是array类型的时候,单纯判断dataIndex的value是否相等 * 根据dataIndex的value值来确定是否合并 * hint: 如果该dataIndex存在render且返回值并非是React.Element的情况 * 则判断使用者使用自己规定的渲染逻辑,则放弃重写渲染函数 */ if (collapseRow && Array.isArray(collapseRow)) { // 如果存在合并行的配置信息 // 判断该dataIndex是否存在render函数且render函数包含合并的处理信息 const collapseRowItems = [] collapseRow.forEach((item) => { const _tar = sourceColumns.find((i) => { const colName = i.key || i.dataIndex return colName === item }) if (_tar) collapseRowItems.push(_tar) }) // 检查render中是否存在合并的配置 const dataIndexExclude = haveProps(collapseRowItems, 'rowSpan') // 如果返回值都是false那么意味用户传入的数组的每个dataIndex都需要写入render // 如果返回是一个数组,则数组内的dataIndex的render函数则不能重写 const shouldRerender = difference(collapseRow, dataIndexExclude) const rowSpanData = getRowSpanDataByArray(shouldRerender, dataSource) const processedColumns = sourceColumns.map((item) => { const colName = item.key || item.dataIndex const tarIndex = shouldRerender.findIndex(i => i === colName) if (tarIndex >= 0) { // 重写render函数 const ORIGINALRENDER = item.render item.render = (text, row, index) => { const dataCollections = rowSpanData[text] const currentSet = dataCollections.filter(i => i.start === index) const rowSpan = currentSet.length > 0 ? currentSet[0].length : 0 return { children: ORIGINALRENDER ? ORIGINALRENDER.call(this, text, row, index) : text, props: { rowSpan, }, } } } return item }) return processedColumns } else { // 错误提示 console.error('[warning]value of collapseRow got undefined or wrong type, which except an array-type') console.error('[unexcept output]we will ignore the props of "collapseRow" in this instance') } return sourceColumns } export default formatColumns