UNPKG

vue-easytable

Version:
672 lines (601 loc) 18.5 kB
import BodyCheckboxContent from "./body-checkbox-content"; import BodyRadioContent from "./body-radio-content"; import ExpandTrIcon from "./expand-tr-icon"; import { clsName, getRowKeysByRangeRowKeys } from "../util"; import { isNumber, isBoolean, isEmptyValue } from "../../../src/utils/index.js"; import { COMPS_NAME, COLUMN_TYPES, EXPAND_TRIGGER_TYPES, EMIT_EVENTS, COMPS_CUSTOM_ATTRS, } from "../util/constant"; import emitter from "../../../src/mixins/emitter"; export default { name: COMPS_NAME.VE_TABLE_BODY_TD, mixins: [emitter], props: { rowData: { type: Object, required: true, }, column: { type: Object, required: true, }, columnCollection: { type: Array, required: true, }, rowIndex: { type: Number, required: true, }, colgroups: { type: Array, required: true, }, rowKeyFieldName: { type: String, default: null, }, allRowKeys: { type: Array, required: true, }, /* expand */ // expand row option expandOption: { type: Object, default: function () { return null; }, }, // is expand row isExpandRow: { type: Boolean, required: true, }, // expanded row keys expandedRowkeys: { type: Array, default: function () { return []; }, }, /* checkbox */ // checkbox option checkboxOption: { type: Object, default: function () { return null; }, }, internalCheckboxSelectedRowKeys: { type: Array, default: function () { return null; }, }, /* radio */ radioOption: { type: Object, default: function () { return null; }, }, internalRadioSelectedRowKey: { type: [String, Number], default: null, }, // cell style option cellStyleOption: { type: Object, default: function () { return null; }, }, // event custom option eventCustomOption: { type: Object, default: function () { return null; }, }, // cell selection data cellSelectionData: { type: Object, default: function () { return null; }, }, // cell selection range data cellSelectionRangeData: { type: Object, default: function () { return null; }, }, bodyIndicatorRowKeys: { type: Object, default: function () { return null; }, }, // cell span option cellSpanOption: { type: Object, default: function () { return null; }, }, // edit opttion editOption: { type: Object, default: function () { return null; }, }, }, data() { return { // 原始单元格数据 rawCellValue: "", }; }, computed: { /* current column collection item 1、Cache the style、class of each column */ currentColumnCollectionItem() { const { columnCollection, column } = this; return columnCollection.find((x) => x.colKey === column.key); }, // current row key currentRowKey() { const { rowData, rowKeyFieldName } = this; return rowData[rowKeyFieldName]; }, }, watch: { // watch row data rowData: { handler(rowData) { const column = this.column; if (column) { this.rawCellValue = rowData[column.field]; } }, deep: true, immediate: true, }, }, methods: { /* * @bodyTdStyle * @desc body td style */ bodyTdStyle() { const { currentColumnCollectionItem } = this; let result = {}; if (currentColumnCollectionItem) { result = Object.assign( result, currentColumnCollectionItem.style, ); } return result; }, /* * @bodyTdClass * @desc body td class */ bodyTdClass() { const { currentColumnCollectionItem } = this; const { fixed, operationColumn } = this.column; let result = { [clsName("body-td")]: true, }; const { cellStyleOption, rowData, column, rowIndex, allRowKeys, cellSelectionData, cellSelectionRangeData, bodyIndicatorRowKeys, currentRowKey, } = this; // column fixed if (fixed) { result[clsName("fixed-left")] = fixed === "left"; result[clsName("fixed-right")] = fixed === "right"; } // operation column if (operationColumn) { result[clsName("operation-col")] = true; } // cell style option if ( cellStyleOption && typeof cellStyleOption.bodyCellClass === "function" ) { const customClass = cellStyleOption.bodyCellClass({ row: rowData, column, rowIndex, }); if (customClass) { result[customClass] = true; } } if (cellSelectionData) { const { rowKey, colKey } = cellSelectionData.currentCell; if (!isEmptyValue(rowKey) && !isEmptyValue(colKey)) { if (currentRowKey === rowKey) { // cell selection if (column["key"] === colKey) { result[clsName("cell-selection")] = true; } } if (operationColumn) { const { topRowKey, bottomRowKey } = cellSelectionRangeData; const { startRowKeyIndex } = bodyIndicatorRowKeys; const isIndicatorActive = startRowKeyIndex > -1; let indicatorRowKeys = []; if (topRowKey === bottomRowKey) { indicatorRowKeys = [topRowKey]; } else { indicatorRowKeys = getRowKeysByRangeRowKeys({ topRowKey, bottomRowKey, allRowKeys, }); } // cell indicator (operation column) if (indicatorRowKeys.indexOf(currentRowKey) > -1) { if (isIndicatorActive) { result[clsName("cell-indicator-active")] = true; } else { result[clsName("cell-indicator")] = true; } } } } } if (currentColumnCollectionItem) { result = Object.assign( result, currentColumnCollectionItem.class, ); } return result; }, // get ellipsis content style getEllipsisContentStyle() { let result = {}; const { ellipsis } = this.column; if (ellipsis) { const { lineClamp } = ellipsis; let _lineClamp = isNumber(lineClamp) ? lineClamp : 1; result["-webkit-line-clamp"] = _lineClamp; } return result; }, // get render content getRenderContent(h) { let content = null; const { column, rowData, rowIndex, rawCellValue } = this; // has render function if (typeof column.renderBodyCell === "function") { const renderResult = column.renderBodyCell( { row: rowData, column, rowIndex, }, h, ); content = renderResult; } else { content = rawCellValue; } // ellipisis if (column.ellipsis) { const { showTitle } = column.ellipsis; // default true const isShowTitle = isBoolean(showTitle) ? showTitle : true; content = ( <span title={isShowTitle ? content : ""} style={this.getEllipsisContentStyle()} class={clsName("body-td-span-ellipsis")} > {content} </span> ); } return content; }, // get chcekbox content getCheckboxContent() { if (this.column.type === COLUMN_TYPES.CHECKBOX) { // checkbox content props const checkboxProps = { props: { column: this.column, checkboxOption: this.checkboxOption, rowKey: this.rowData[this.rowKeyFieldName], internalCheckboxSelectedRowKeys: this.internalCheckboxSelectedRowKeys, }, }; return <BodyCheckboxContent {...checkboxProps} />; } return null; }, // get radio content getRadioContent() { if (this.column.type === COLUMN_TYPES.RADIO) { // radio props const radioProps = { props: { column: this.column, radioOption: this.radioOption, rowKey: this.rowData[this.rowKeyFieldName], internalRadioSelectedRowKey: this.internalRadioSelectedRowKey, }, }; return <BodyRadioContent {...radioProps} />; } return null; }, // get cell span getCellSpan() { const { cellSpanOption, rowData, column, rowIndex } = this; let rowspan = 1; let colspan = 1; if (cellSpanOption) { const { bodyCellSpan } = cellSpanOption; if (typeof bodyCellSpan === "function") { const result = bodyCellSpan({ row: rowData, column, rowIndex, }); if (typeof result === "object") { rowspan = result.rowspan; colspan = result.colspan; } } } return { rowspan, colspan }; }, // cell click cellClick(e, fn) { fn && fn(e); const { column, expandOption, rowData } = this; this.dispatch(COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_CLICK, { event: e, rowData, column, }); if (column.type !== COLUMN_TYPES.EXPAND) { return false; } if (expandOption) { const eventTargetName = e.target.nodeName; const trigger = expandOption.trigger; // expand row by click icon if (!trigger || trigger === EXPAND_TRIGGER_TYPES.ICON) { if (eventTargetName !== "TD") { e.stopPropagation(); this.$emit(EMIT_EVENTS.EXPAND_ROW_CHANGE); } } // expand row by click cell(td) else if (trigger === EXPAND_TRIGGER_TYPES.CELL) { e.stopPropagation(); this.$emit(EMIT_EVENTS.EXPAND_ROW_CHANGE); } } }, // dblclick cellDblclick(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_DOUBLE_CLICK, { event: e, rowData, column, }, ); }, // contextmenu cellContextmenu(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_CONTEXTMENU, { event: e, rowData, column, }, ); }, // mouseenter cellMouseenter(e, fn) { fn && fn(e); }, // mouseleave cellMouseleave(e, fn) { fn && fn(e); }, // mousemove cellMousemove(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_MOUSEMOVE, { event: e, rowData, column, }, ); }, // mouseover cellMouseover(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_MOUSEOVER, { event: e, rowData, column, }, ); }, // mousedown cellMousedown(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_MOUSEDOWN, { event: e, rowData, column, }, ); }, // mouseup cellMouseup(e, fn) { fn && fn(e); const { column, rowData } = this; this.dispatch(COMPS_NAME.VE_TABLE, EMIT_EVENTS.BODY_CELL_MOUSEUP, { event: e, rowData, column, }); }, }, render(h) { const { column, cellClick, rowData, isExpandRow, expandOption, expandedRowkeys, rowKeyFieldName, eventCustomOption, rowIndex, } = this; // expand icon props const expandIconProps = { props: { rowData, column, expandOption, expandedRowkeys, rowKeyFieldName, cellClick, }, }; const { rowspan, colspan } = this.getCellSpan(); if (!rowspan || !colspan) { return null; } // custom on cell event let customEvents = {}; if (eventCustomOption) { const { bodyCellEvents } = eventCustomOption; customEvents = bodyCellEvents ? bodyCellEvents({ row: rowData, column, rowIndex }) : {}; } const { click, dblclick, contextmenu, mouseenter, mouseleave, mousemove, mouseover, mousedown, mouseup, } = customEvents; const events = { click: (e) => { this.cellClick(e, click); }, dblclick: (e) => { this.cellDblclick(e, dblclick); }, contextmenu: (e) => { this.cellContextmenu(e, contextmenu); }, mouseenter: (e) => { this.cellMouseenter(e, mouseenter); }, mouseleave: (e) => { this.cellMouseleave(e, mouseleave); }, mousemove: (e) => { this.cellMousemove(e, mousemove); }, mouseover: (e) => { this.cellMouseover(e, mouseover); }, mousedown: (e) => { this.cellMousedown(e, mousedown); }, mouseup: (e) => { this.cellMouseup(e, mouseup); }, }; // td props const tdProps = { class: this.bodyTdClass(), style: this.bodyTdStyle(), attrs: { rowspan, colspan, [COMPS_CUSTOM_ATTRS.BODY_COLUMN_KEY]: column.key, }, on: events, }; return ( <td {...tdProps}> {/* expadn tr icon */} {isExpandRow && <ExpandTrIcon {...expandIconProps} />} {/* checkbox content */} {this.getCheckboxContent()} {/* radio content */} {this.getRadioContent()} {/* other cell content */} {this.getRenderContent(h)} </td> ); }, };