mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-12-16 12:26:57 +08:00
225 lines
5.3 KiB
Vue
225 lines
5.3 KiB
Vue
<template>
|
|
<TMagicTable
|
|
v-loading="loading"
|
|
class="m-table"
|
|
ref="tMagicTable"
|
|
:show-overflow-tooltip="true"
|
|
tooltip-effect="dark"
|
|
:tooltip-options="{ popperOptions: { strategy: 'absolute' } }"
|
|
:data="tableData"
|
|
:show-header="showHeader"
|
|
:max-height="bodyHeight"
|
|
:default-expand-all="defaultExpandAll"
|
|
:border="hasBorder"
|
|
:row-key="rowkeyName || 'id'"
|
|
:tree-props="{ children: 'children' }"
|
|
:empty-text="emptyText || '暂无数据'"
|
|
:span-method="objectSpanMethod"
|
|
:columns="tableColumns"
|
|
@sort-change="sortChange"
|
|
@select="selectHandler"
|
|
@select-all="selectAllHandler"
|
|
@selection-change="selectionChangeHandler"
|
|
@cell-click="cellClickHandler"
|
|
@expand-change="expandChange"
|
|
></TMagicTable>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, h, ref, useTemplateRef } from 'vue';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
import { TMagicTable } from '@tmagic/design';
|
|
|
|
import ActionsColumn from './ActionsColumn.vue';
|
|
import ComponentColumn from './ComponentColumn.vue';
|
|
import ExpandColumn from './ExpandColumn.vue';
|
|
import PopoverColumn from './PopoverColumn.vue';
|
|
import type { ColumnConfig } from './schema';
|
|
import TextColumn from './TextColumn.vue';
|
|
|
|
defineOptions({
|
|
name: 'MTable',
|
|
});
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
data: any[];
|
|
columns?: ColumnConfig[];
|
|
/** 合并行或列的计算方法 */
|
|
spanMethod?: (_data: { row: any; column: any; rowIndex: number; columnIndex: number }) => [number, number];
|
|
loading?: boolean;
|
|
/** Table 的最大高度。合法的值为数字或者单位为 px 的高度 */
|
|
bodyHeight?: string | number;
|
|
/** 是否显示表头 */
|
|
showHeader?: boolean;
|
|
/** 空数据时显示的文本内容 */
|
|
emptyText?: string;
|
|
/** 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 */
|
|
defaultExpandAll?: boolean;
|
|
rowkeyName?: string;
|
|
/** 是否带有纵向边框 */
|
|
border?: boolean;
|
|
}>(),
|
|
{
|
|
columns: () => [],
|
|
loading: false,
|
|
showHeader: true,
|
|
defaultExpandAll: false,
|
|
border: false,
|
|
},
|
|
);
|
|
|
|
const emit = defineEmits([
|
|
'sort-change',
|
|
'after-action',
|
|
'select',
|
|
'select-all',
|
|
'selection-change',
|
|
'expand-change',
|
|
'cell-click',
|
|
]);
|
|
|
|
const cellRender = (config: ColumnConfig, { row = {}, $index }: any) => {
|
|
if (config.type === 'expand') {
|
|
return h(ExpandColumn, {
|
|
config,
|
|
row,
|
|
});
|
|
}
|
|
if (config.type === 'component') {
|
|
return h(ComponentColumn, {
|
|
config,
|
|
row,
|
|
index: $index,
|
|
});
|
|
}
|
|
if (config.actions) {
|
|
return h(ActionsColumn, {
|
|
config,
|
|
row,
|
|
index: $index,
|
|
rowkeyName: props.rowkeyName,
|
|
editState: editState.value,
|
|
columns: props.columns,
|
|
});
|
|
}
|
|
if (config.type === 'popover') {
|
|
return h(PopoverColumn, {
|
|
config,
|
|
row,
|
|
index: $index,
|
|
});
|
|
}
|
|
return h(TextColumn, {
|
|
config,
|
|
row,
|
|
index: $index,
|
|
editState: editState.value,
|
|
});
|
|
};
|
|
|
|
const tableColumns = computed(() =>
|
|
props.columns.map((item) => {
|
|
let type: 'default' | 'selection' | 'index' | 'expand' = 'default';
|
|
if (item.type === 'expand') {
|
|
type = 'expand';
|
|
} else if (item.selection) {
|
|
type = 'selection';
|
|
}
|
|
|
|
return {
|
|
props: {
|
|
label: item.label,
|
|
fixed: item.fixed,
|
|
width: item.width ?? (item.selection ? 40 : undefined),
|
|
prop: item.prop,
|
|
type,
|
|
selectable: item.selectable,
|
|
},
|
|
cell: type === 'selection' ? undefined : ({ row, $index }: any) => cellRender(item, { row, $index }),
|
|
};
|
|
}),
|
|
);
|
|
|
|
const tMagicTableRef = useTemplateRef('tMagicTable');
|
|
|
|
const editState = ref([]);
|
|
|
|
const selectionColumn = computed(() => {
|
|
const column = props.columns.filter((item) => item.selection);
|
|
return column.length ? column[0] : null;
|
|
});
|
|
|
|
const tableData = computed(() => {
|
|
if (selectionColumn.value) {
|
|
return props.data || [];
|
|
}
|
|
|
|
return cloneDeep(props.data) || [];
|
|
});
|
|
|
|
const hasBorder = computed(() => (typeof props.border !== 'undefined' ? props.border : true));
|
|
|
|
const sortChange = (data: any) => {
|
|
emit('sort-change', data);
|
|
};
|
|
|
|
const selectHandler = (selection: any, row: any) => {
|
|
const column = selectionColumn.value;
|
|
if (!column) {
|
|
return;
|
|
}
|
|
|
|
if (column.selection === 'single') {
|
|
// this.clearSelection()
|
|
// this.toggleRowSelection(row, true)
|
|
}
|
|
emit('select', selection, row);
|
|
};
|
|
|
|
const selectAllHandler = (selection: any) => {
|
|
emit('select-all', selection);
|
|
};
|
|
|
|
const selectionChangeHandler = (selection: any) => {
|
|
emit('selection-change', selection);
|
|
};
|
|
|
|
const cellClickHandler = (...args: any[]) => {
|
|
emit('cell-click', ...args);
|
|
};
|
|
|
|
const expandChange = (...args: any[]) => {
|
|
emit('expand-change', ...args);
|
|
};
|
|
|
|
const toggleRowSelection = (row: any, selected: boolean) => {
|
|
tMagicTableRef.value?.toggleRowSelection(row, selected);
|
|
};
|
|
|
|
const toggleRowExpansion = (row: any, expanded: boolean) => {
|
|
tMagicTableRef.value?.toggleRowExpansion(row, expanded);
|
|
};
|
|
|
|
const clearSelection = () => {
|
|
tMagicTableRef.value?.clearSelection();
|
|
};
|
|
|
|
const objectSpanMethod = (data: any) => {
|
|
if (typeof props.spanMethod === 'function') {
|
|
return props.spanMethod(data);
|
|
}
|
|
return () => ({
|
|
rowspan: 0,
|
|
colspan: 0,
|
|
});
|
|
};
|
|
|
|
defineExpose({
|
|
toggleRowSelection,
|
|
toggleRowExpansion,
|
|
clearSelection,
|
|
});
|
|
</script>
|