UNPKG

kingdot

Version:

A UI Components Library For Vue

516 lines (509 loc) 23.2 kB
import myColgroup from './colgroup.js'; export default { name: 'TableBody', props: { store: { type: Object, default: {} }, marginLeft: { type: [String], default: "0px" }, width: [String], treeProps: { type: Object }, hoverIndex: {} }, computed: { columns() { //return this.store.states.columns; return this.getAllCols(); }, rowsData() { return this.store.states.data; }, expandData() { return this.store.states.expand; }, table() { return this.$parent; }, disableCache() { return this.$parent.disableCache; }, firstColumnIndex() { return this.store.states.showCheckbox ? 1 : 0; }, childRenKey() { if (this.treeProps) { return this.treeProps.children || 'children'; } else { return null } }, hasChildrenKey() { if (this.treeProps) { return this.treeProps.hasChildren || 'hasChildren'; } else { return null } }, noData() { return this.store.states.data.length == 0; } }, components: { myColgroup }, methods: { clickRow(v,index) { this.table.clickRow(v.originData, index); }, getCols(item) { let columns = [ item.props || item.renderColumnFn ? Object.assign({}, item) : null ]; let nextCol = []; if (item.children && item.children.length) { item.children.map(inner => { nextCol = this.getCols(inner); columns = columns.concat(nextCol); }) } return columns; }, //当合并表头时,需要拉平children层级。通过store里的columns和TableBody的columns的length对比可以知道是否合并表头 getAllCols() { let columns = []; this.store.states.columns.map(item => { columns = columns.concat(this.getCols(item)); }); // console.log(columns) return columns; }, getRealyProps(data, propsArray) { if (!data) return ""; if (!propsArray) return ""; if (propsArray.length > 1) { var _data = data[propsArray[0]]; propsArray.shift(); return this.getRealyProps(_data, propsArray); } else { return data[propsArray[0]]; } }, getHeight() { if (this.$refs.tableBody) { return this.$refs.tableBody.offsetHeight; } }, //开关父节点下的所有子节点tree triggerTree(rowsItem, flag) { !flag && this.calleeTreeData(rowsItem); }, calleeTreeData(rowsItem) { if (this.disableCache && rowsItem.loadTree != undefined && rowsItem[this.childRenKey] && rowsItem[this.hasChildrenKey]) { rowsItem[this.childRenKey] && (rowsItem[this.childRenKey] = []); } if (!rowsItem[this.childRenKey]) return false; rowsItem[this.childRenKey].map(item => { item.showTree = false; item[this.childRenKey] && this.calleeTreeData(item); }); this.table.resize(); }, //显示tr下tree normal showTrTree(rowsItem) { rowsItem.showTree = !rowsItem.showTree; this.$nextTick(() => { this.triggerTree(rowsItem.originData || rowsItem, rowsItem.showTree) }) }, //显示tr下的tree lazy load showLazyLoadTree(item, parent = {}, rowsItem) { item.loadTree = true; new Promise(resolve => { this.table.treeLoad(parent, item, resolve); }).then(data => { item.loadTree = false; let childRenKey = this.childRenKey || 'children'; if (data && data.length) { item[childRenKey] = data; } this.$nextTick(() => { rowsItem.showTree = true; }) }) }, //处理表格合并 getSpan(row, column, rowIndex, columnIndex) { let rowspan = 1; let colspan = 1; const fn = this.table.spanMethod; if (typeof fn === 'function') { const result = fn({ row, column, rowIndex, columnIndex }); if (Array.isArray(result)) { rowspan = result[0]; colspan = result[1]; } else if (typeof result === 'object') { rowspan = result.rowspan; colspan = result.colspan; } } return {rowspan, colspan}; }, // hover hoverTr(index) { this.$emit('setHover', index) }, //普通tr renderTr(rowsItem, index) { let data = rowsItem.originData; let hasChildren = data[this.childRenKey] && data[this.childRenKey].length; //重置数据 data.loadTree == undefined && this.$set(data, "loadTree", false); data[this.childRenKey] == undefined && this.$set(data, this.childRenKey, []); return ( <tr key={rowsItem.key} class={ { 'kd-disabled': rowsItem.disabled, 'kd-tr-hover': this.hoverIndex == index } } on-click={v => { v.target.tagName == 'TD' && this.clickRow(rowsItem, index) }} on-mousemove={v => {this.hoverTr(index)}} on-mouseout={v => {this.hoverTr(null)}} > { this.columns.map((columnItem, cellIndex) => { let scopeData = { data: rowsItem, $index: index, row: rowsItem.originData, store: this.store, _self: this.$parent.$vnode.context }; const {rowspan, colspan} = this.getSpan(rowsItem.originData, columnItem, index, cellIndex); if (!rowspan || !colspan) { return null; } return ( columnItem ? <td style={{ paddingLeft: !this.store.states.showCheckbox && cellIndex == 0 ? "20px" : "" }} rowspan={rowspan} colspan={colspan} > { ( this.treeProps && cellIndex == this.firstColumnIndex && ( hasChildren || data[this.hasChildrenKey] ) ) && ( <span class={[ "kd-table-btn", "kd-table-tree-btn", "kd-icon-arrow-down", { "kd-icon-loading1": data.loadTree, "kd-table-loading": data.loadTree, "kd-table-show-btn": rowsItem.showTree } ]} on-click={v => { if (data[this.hasChildrenKey] && !hasChildren) { this.showLazyLoadTree(data, data, rowsItem); } else { this.showTrTree(rowsItem); } }} ></span> ) } { columnItem._slotColumn ? columnItem.renderColumnFn.call( this._renderProxy, h, scopeData ) : this.getRealyProps( rowsItem.originData, columnItem.props ? columnItem.props.split(".") : null ) } </td> : null ) }) } </tr> ) }, //包含expand的tr renderExpandTr() { let renderTr = this.rowsData.map((rowsItem, index) => { return ( [ this.renderTr(rowsItem, index), this.expandData ? ( rowsItem.showExpand && ( <tr class="kd-table-tr-expand"> <td colspan={ this.columns.length + (this.store.states.showCheckbox ? 1 : 0) }> { this.expandData._slotColumn ? this.expandData.renderColumnFn.call( this._renderProxy, h, { data: rowsItem, store: this.store, row: rowsItem.originData } ) : ('') } </td> </tr> ) ) : ('') ] ) }); return renderTr; }, //包含tree的tr renderTreeTr(rowsItem, index, step) { if (!this.childRenKey) return []; let trList = []; let nextLevel = []; step = step ? step += 1 : 0; let Items = rowsItem.originData || rowsItem; if (!Items[this.childRenKey]) return []; Items[this.childRenKey].map((item, nCount) => { //重置数据 item.loadTree == undefined && this.$set(item, "loadTree", false); item[this.childRenKey] == undefined && this.$set(item, this.childRenKey, []); item.showTree == undefined && this.$set(item, "showTree", false); item.disabled == undefined && this.$set(item, "disabled", rowsItem.disabled); item.key == undefined && this.$set(item, "key", rowsItem.key + '_' + nCount); let hasChildren = item[this.childRenKey] && item[this.childRenKey].length; trList.push( rowsItem.showTree || item.showTree ? ( <tr key={item.key} class={ { 'kd-disabled': item.disabled } } > { this.columns.map((columnItem, cellIndex) => { let scopeData = { data: item, $parent: rowsItem.originData || rowsItem, $index: index, $childrenIndex: nCount, row: item, store: this.store, _self: this.$parent.$vnode.context }; return ( <td style={{ paddingLeft: !this.store.states.showCheckbox && cellIndex == 0 ? "20px" : "" }}> { cellIndex == this.firstColumnIndex && ( <span class="kd-table-tree-placeholder" style={ { "width": 24 * step + 'px' } }></span> ) } { ( this.treeProps && cellIndex == this.firstColumnIndex && ( hasChildren || item[this.hasChildrenKey] ) ) && ( <span class={[ "kd-table-btn", "kd-table-tree-btn", "kd-icon-arrow-down", { "kd-icon-loading1": item.loadTree, "kd-table-loading": item.loadTree, "kd-table-show-btn": item.showTree } ]} on-click={v => { if (item[this.hasChildrenKey] && !hasChildren) { this.showLazyLoadTree(item, rowsItem.originData, item); } else { this.showTrTree(item); } }} ></span> ) } { columnItem._slotColumn ? columnItem.renderColumnFn.call( this._renderProxy, h, scopeData ) : this.getRealyProps( item, columnItem.props ? columnItem.props.split(".") : null ) } </td> ) }) } </tr> ) : ('') ); //如果有children if (item[this.childRenKey] && item[this.childRenKey].length) { nextLevel = this.renderTreeTr(item, nCount, step); trList = trList.concat(nextLevel); } }); return trList; }, renderTree() { let renderTr = this.rowsData.map((rowsItem, index) => { let normal = [this.renderTr(rowsItem, index)]; let tree = this.renderTreeTr(rowsItem, index, 1); return normal.concat(tree); }); return renderTr; }, }, render() { const renderNormalTr = this.treeProps ? this.renderTree() : this.renderExpandTr(); return ( <div class="kd-table-body"> <table cellSpacing="0" cellPadding="0" border="0" ref="tableBody" style={{ width: this.width, marginLeft: this.marginLeft }} > { //判断是否是合并表头模式 this.columns.length == this.store.states.columns.length ? <my-colgroup store={this.store}></my-colgroup> : <colgroup> { this.columns.map(item => { return ( item ? <col name={item.key} width={item.width || this.store._autoColumnWidth}></col> : '' ) }) } </colgroup> } <tbody> { renderNormalTr } { this.noData && ( <tr> <td style="text-align: center;" colspan={ this.columns.length } > 无数据 </td> </tr> ) } </tbody> </table> </div> ); } }