Browse Source

1、表格列隐藏与form中统一使用showIf。

2、支持hideHeader属性。
main
likunming 4 months ago
parent
commit
0a15224d65
  1. 8
      io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue
  2. 99
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  3. 6
      io.sc.platform.core.frontend/src/platform/components/grid/css/separator.css
  4. 23
      io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts

8
io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue

@ -93,7 +93,7 @@
unelevated unelevated
@click=" @click="
() => { () => {
table.columns[0].hidden = false; table.columns[0].showIf = true;
table.sortNo = true; table.sortNo = true;
grid.refreshStyle(100); grid.refreshStyle(100);
} }
@ -107,7 +107,7 @@
unelevated unelevated
@click=" @click="
() => { () => {
table.columns[0].hidden = true; table.columns[0].showIf = false;
table.sortNo = false; table.sortNo = false;
grid.refreshStyle(100); grid.refreshStyle(100);
} }
@ -238,9 +238,7 @@
<q-item v-if="showColumn(col.name)" v-ripple tag="label" dense> <q-item v-if="showColumn(col.name)" v-ripple tag="label" dense>
<q-item-section side> <q-item-section side>
<q-checkbox <q-checkbox
v-model="col.hidden" v-model="col.showIf"
:false-value="true"
:true-value="false"
dense dense
@update:model-value=" @update:model-value="
() => { () => {

99
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -11,6 +11,7 @@
:loading-label="$t('tip.dataLoading')" :loading-label="$t('tip.dataLoading')"
v-bind="attrs" v-bind="attrs"
:separator="table.separator" :separator="table.separator"
:hide-header="props.hideHeader"
:selection="selectionComputed" :selection="selectionComputed"
:rows="table.rows" :rows="table.rows"
:columns="columnsComputed" :columns="columnsComputed"
@ -18,7 +19,6 @@
:loading="state.loading" :loading="state.loading"
:class="tableClassComputed" :class="tableClassComputed"
:table-style="tableHeightComputed" :table-style="tableHeightComputed"
card-container-class="card-container-class3333"
:row-key="rowKey_" :row-key="rowKey_"
:visible-columns="visibleColumnsComputed" :visible-columns="visibleColumnsComputed"
:hide-bottom="pageable && !props.localMode && !tree ? false : true" :hide-bottom="pageable && !props.localMode && !tree ? false : true"
@ -95,6 +95,11 @@
:request="onRequest" :request="onRequest"
></GridPagination> ></GridPagination>
</template> </template>
<!-- 隐藏表头且无数据时 -->
<template v-if="table.rows.length === 0 && props.hideHeader" #top-row>
<div :style="hideHeaderAndNoDataStyleComputed"><q-icon size="2em" name="info" />{{ $t('tip.noData') }}</div>
</template>
</q-table> </q-table>
<!-- 新增与编辑窗口 --> <!-- 新增与编辑窗口 -->
@ -128,7 +133,7 @@ import GridPagination from './GridPagination.vue';
import GridEditor from './GridEditor.vue'; import GridEditor from './GridEditor.vue';
import CellEditor from './CellEditor.vue'; import CellEditor from './CellEditor.vue';
import GridView from './GridView.vue'; import GridView from './GridView.vue';
import { selectMode as selectMode_, getMergeColumns, sortByProperties, editStatus } from './ts/grid.ts'; import { selectMode as selectMode_, sortByProperties, editStatus, groupMode as groupMode_ } from './ts/grid.ts';
import { columnDefaultProps } from './ts/grid.ts'; import { columnDefaultProps } from './ts/grid.ts';
@ -183,10 +188,13 @@ const props = defineProps({
foreignKey: { type: String, default: 'parent' }, // foreignKey: { type: String, default: 'parent' }, //
refreshData: { type: Boolean, default: false }, // primaryKey refreshData: { type: Boolean, default: false }, // primaryKey
dbClickOperation: { type: String, default: 'view' }, // nameclickexpand()none() dbClickOperation: { type: String, default: 'view' }, // nameclickexpand()none()
separator: { type: String, default: 'horizontal' }, separator: { type: String, default: 'cell' }, // 线horizontalverticalcellnone
groupMode: { type: String, default: '' }, hideHeader: { type: Boolean, default: false }, //
group: { groupMode: { type: String, default: undefined }, // alonemerge
type: Array, groupStartOpen: { type: [String, Array], default: undefined }, // aloneallfirstnone
groupByField: {
// alone
type: [String, Array],
default: () => { default: () => {
return []; return [];
}, },
@ -343,7 +351,6 @@ const tableColumnsMap = ref(arrayToMap('name', rawColumns.value));
const rowKey_ = '_rowKey_'; // UUID const rowKey_ = '_rowKey_'; // UUID
const queryFormFieldsMap = arrayToMap('name', props.queryFormFields); const queryFormFieldsMap = arrayToMap('name', props.queryFormFields);
const tableColumns = ref(columnDefaultProps(rawColumns.value, props.sortNo)); const tableColumns = ref(columnDefaultProps(rawColumns.value, props.sortNo));
const mergeColumns = getMergeColumns(tableColumns.value);
const url = { const url = {
dataUrl: props.dataUrl, dataUrl: props.dataUrl,
fetchDataUrl: props.fetchDataUrl, fetchDataUrl: props.fetchDataUrl,
@ -450,8 +457,12 @@ const denseBottomComputed = computed(() => {
const visibleColumnsComputed = computed(() => { const visibleColumnsComputed = computed(() => {
const visibleColumns: string[] = []; const visibleColumns: string[] = [];
table.columns.forEach((item) => { table.columns.forEach((item) => {
if (!item.hidden && (!props.tree || (props.tree && item.name !== '_sortNo_'))) { if (!props.tree || (props.tree && item.name !== '_sortNo_')) {
visibleColumns.push(item.name); if (Tools.isEmpty(item.showIf)) {
visibleColumns.push(item.name);
} else if (typeof item.showIf === 'boolean' && item.showIf) {
visibleColumns.push(item.name);
}
} }
}); });
return visibleColumns; return visibleColumns;
@ -472,8 +483,8 @@ const state = reactive({
middleScrollWidth: 0, // middleWidth middleScrollWidth: 0, // middleWidth
middleHeight: 0, // middle() middleHeight: 0, // middle()
columnHeadHeight: 0, // columnHeadHeight: 0, //
tableTitleWidth: 0, // title
titleTotalHeight: 0, // title titleTotalHeight: 0, // title
hideHeaderNoDataHeight: 0, //
}, },
pagination: { pagination: {
config: { config: {
@ -559,6 +570,14 @@ const noDataTrHeightComputed = computed(() => {
}; };
return style; return style;
}); });
const hideHeaderAndNoDataStyleComputed = computed(() => {
return {
height: state.refHeightWidth.hideHeaderNoDataHeight + 'px',
display: 'flex',
'align-items': 'center',
'justify-content': 'center',
};
});
const noDataTrColspanComputed = computed(() => { const noDataTrColspanComputed = computed(() => {
let colspan = excludeColumnNum.value; let colspan = excludeColumnNum.value;
@ -625,6 +644,7 @@ const onResize = () => {
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth; state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth; state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight; state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.hideHeaderNoDataHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
// middleHeight // middleHeight
if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) { if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) {
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight; state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
@ -635,12 +655,15 @@ const onResize = () => {
} }
state.refHeightWidth.middleHeight = state.refHeightWidth.columnHeadHeight + scrollHeight; state.refHeightWidth.middleHeight = state.refHeightWidth.columnHeadHeight + scrollHeight;
} }
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth; let titleTotalHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.offsetHeight;
let titleTotalHeight = tableRef.value.$el.getElementsByTagName('thead')[0].offsetHeight;
// top // top
if (table.rows.length === 0) { if (table.rows.length === 0) {
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0].offsetHeight; const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.offsetHeight;
titleTotalHeight = titleTotalHeight - noDataTrHeight; if (titleTotalHeight && titleTotalHeight > 0) {
titleTotalHeight = titleTotalHeight - noDataTrHeight;
} else {
titleTotalHeight = noDataTrHeight;
}
} }
state.refHeightWidth.titleTotalHeight = titleTotalHeight; state.refHeightWidth.titleTotalHeight = titleTotalHeight;
} }
@ -901,10 +924,10 @@ const initRowDataExtraProperty = (rowData) => {
* @param rows 数据行集合 * @param rows 数据行集合
*/ */
const setRowDataExtraProperty = (rows: []) => { const setRowDataExtraProperty = (rows: []) => {
if (mergeColumns.length > 0 && !props.tree) { if (props.groupMode === groupMode_.merge && !props.tree) {
// //
table.mergeRecords = {}; table.mergeRecords = {};
sortByProperties(rows, mergeColumns); // sortByProperties(rows, mergeColumns);
} }
if (rows && rows.length > 0) { if (rows && rows.length > 0) {
rows.forEach((item: any, index) => { rows.forEach((item: any, index) => {
@ -954,20 +977,20 @@ const setOldValue = (rowData) => {
* desc: { 天安门: [5,1] } * desc: { 天安门: [5,1] }
*/ */
const addMergeRecords = (rowData) => { const addMergeRecords = (rowData) => {
if (mergeColumns.length > 0 && !props.tree) { // if (mergeColumns.length > 0 && !props.tree) {
mergeColumns.forEach((columnName) => { // mergeColumns.forEach((columnName) => {
const tmpArr = [rowData[rowDataExtraPropertyName.rowKey]]; // const tmpArr = [rowData[rowDataExtraPropertyName.rowKey]];
if (table.mergeRecords[columnName]) { // if (table.mergeRecords[columnName]) {
if (table.mergeRecords[columnName][rowData[columnName]]) { // if (table.mergeRecords[columnName][rowData[columnName]]) {
table.mergeRecords[columnName][rowData[columnName]].push(rowData[rowDataExtraPropertyName.rowKey]); // table.mergeRecords[columnName][rowData[columnName]].push(rowData[rowDataExtraPropertyName.rowKey]);
} else { // } else {
table.mergeRecords[columnName][rowData[columnName]] = tmpArr; // table.mergeRecords[columnName][rowData[columnName]] = tmpArr;
} // }
} else { // } else {
table.mergeRecords[columnName] = { [rowData[columnName]]: tmpArr }; // table.mergeRecords[columnName] = { [rowData[columnName]]: tmpArr };
} // }
}); // });
} // }
}; };
watchEffect(() => { watchEffect(() => {
@ -1004,7 +1027,7 @@ watchEffect(() => {
}); });
const tableClassComputed = computed(() => { const tableClassComputed = computed(() => {
const classArr = <string[]>['sticky-header-column-table', 'w-grid']; const classArr = <string[]>['sticky-header-column-table'];
if (table.stickyNum && table.stickyNum > 0) { if (table.stickyNum && table.stickyNum > 0) {
if (headerRef.value?.getColumnTitleState()?.columnTitleRowNum > 1) { if (headerRef.value?.getColumnTitleState()?.columnTitleRowNum > 1) {
// //
@ -1666,14 +1689,14 @@ const refreshStyle = (time = 500) => {
if (tableRef.value) { if (tableRef.value) {
state.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect()?.y; state.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect()?.y;
if (tableRef.value.$el.getElementsByClassName('noDataTr').length > 0) { if (tableRef.value.$el.getElementsByClassName('noDataTr').length > 0) {
state.refHeightWidth.noDataTrYLocation = tableRef.value.$el.getElementsByClassName('noDataTr')[0].getBoundingClientRect().y; state.refHeightWidth.noDataTrYLocation = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.getBoundingClientRect().y;
} }
state.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight; state.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
state.refHeightWidth.bottomHeight = tableRef.value.$el.getElementsByClassName('q-table__bottom')[0]?.clientHeight; state.refHeightWidth.bottomHeight = tableRef.value.$el.getElementsByClassName('q-table__bottom')[0]?.clientHeight;
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth; state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth; state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight; state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth; state.refHeightWidth.hideHeaderNoDataHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
// middleHeight // middleHeight
if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) { if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) {
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight; state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
@ -1728,11 +1751,15 @@ const refreshStyle = (time = 500) => {
column1Width + column2Width + column3Width + column4Width + column5Width + column6Width + column7Width + column8Width + column9Width + 'px', column1Width + column2Width + column3Width + column4Width + column5Width + column6Width + column7Width + column8Width + column9Width + 'px',
); );
} }
let titleTotalHeight = tableDom.getElementsByTagName('thead')[0].offsetHeight; let titleTotalHeight = tableDom.getElementsByTagName('thead')[0]?.offsetHeight;
// top // top
if (table.rows.length === 0) { if (table.rows.length === 0) {
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0].offsetHeight; const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.offsetHeight;
titleTotalHeight = titleTotalHeight - noDataTrHeight; if (titleTotalHeight && titleTotalHeight > 0) {
titleTotalHeight = titleTotalHeight - noDataTrHeight;
} else {
titleTotalHeight = noDataTrHeight;
}
} }
state.refHeightWidth.titleTotalHeight = titleTotalHeight; state.refHeightWidth.titleTotalHeight = titleTotalHeight;
} }

6
io.sc.platform.core.frontend/src/platform/components/grid/css/separator.css

@ -45,6 +45,9 @@
.w-grid .q-table--vertical-separator th:first-child.firstColumn { .w-grid .q-table--vertical-separator th:first-child.firstColumn {
border-left: 0; border-left: 0;
} }
.w-grid .q-table--vertical-separator th:first-child:not([rowspan]) {
border-left: 0;
}
/* /*
* vertical * vertical
* 数据最后一行底部边框 * 数据最后一行底部边框
@ -71,6 +74,9 @@
.w-grid .q-table--cell-separator th:first-child.firstColumn { .w-grid .q-table--cell-separator th:first-child.firstColumn {
border-left: 0; border-left: 0;
} }
.w-grid .q-table--cell-separator th:first-child:not([rowspan]) {
border-left: 0;
}
/* /*
* cell * cell
* 数据最后一行底部边框 * 数据最后一行底部边框

23
io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts

@ -14,6 +14,12 @@ export const selectMode = {
cell: 'cell', // 单元格选择 cell: 'cell', // 单元格选择
}; };
// 分组模式
export const groupMode = {
alone: 'alone', // 单独行进行分组
merge: 'merge', // 合并行进行分组
};
// 表格内容区域快速编辑状态 // 表格内容区域快速编辑状态
export const editStatus = { export const editStatus = {
none: 'none', // 不在编辑状态 none: 'none', // 不在编辑状态
@ -62,7 +68,7 @@ const childrenHandler = (item: any, gridColumns: any) => {
} else { } else {
columnStyle(item); columnStyle(item);
const col = { const col = {
...{ align: 'left', label: item.name, field: item.name, name: item.name, sortable: true, hidden: false }, ...{ align: 'left', label: item.name, field: item.name, name: item.name, sortable: true, showIf: true },
...item, ...item,
}; };
if (Tools.isEmpty(col.name)) { if (Tools.isEmpty(col.name)) {
@ -76,7 +82,7 @@ const childrenHandler = (item: any, gridColumns: any) => {
export const columnDefaultProps = (columns: any, sortNo: boolean) => { export const columnDefaultProps = (columns: any, sortNo: boolean) => {
const gridColumns = <any>[]; const gridColumns = <any>[];
if (columns && columns.length > 0) { if (columns && columns.length > 0) {
gridColumns.push({ name: '_sortNo_', align: 'center', label: t('rownum'), field: '_sortNo_', hidden: sortNo ? false : true }); gridColumns.push({ name: '_sortNo_', align: 'center', label: t('rownum'), field: '_sortNo_', showIf: sortNo });
columns.forEach((item: any) => { columns.forEach((item: any) => {
childrenHandler(item, gridColumns); childrenHandler(item, gridColumns);
}); });
@ -85,19 +91,6 @@ export const columnDefaultProps = (columns: any, sortNo: boolean) => {
return []; return [];
}; };
// 获取所有需要合并的列名
export const getMergeColumns = (columns) => {
const columnNames = <any>[];
if (columns && columns.length > 0) {
columns.forEach((item) => {
if (Tools.hasOwnProperty(item, 'autoMerge') && item['autoMerge']) {
columnNames.push(item['name']);
}
});
}
return columnNames;
};
export const sortByProperties = (arr, properties) => { export const sortByProperties = (arr, properties) => {
for (const prop of properties) { for (const prop of properties) {
arr.sort((a, b) => { arr.sort((a, b) => {

Loading…
Cancel
Save