<script lang="ts" setup name="NormalTable"> import type { Ref } from 'vue' import { defineExpose } from 'vue' import type { TableColumn } from './table_interface' // ------------------定义props、 emit------------------- const props = defineProps({ // 查询条件,此处主要需要分页的条件 query: { type: Object, default() { return { offset: 1, limit: 20, } }, }, // loading状态 loading: { type: Boolean, default: false, }, // 数据 data: { type: Array, default() { return [] }, }, // 表格高度 height: { type: Number, default() { return null }, }, // 数据总数 total: { type: Number, default: 0, }, // 数据列配置 columns: { type: Array<TableColumn>, default() { return [] }, }, // 是否需要分页控件 pagination: { type: Boolean, default: true, }, // 配置项 options: { type: Object, default() { return { needIndex: true, // 是否需要序号列 border: true, // 是否需要上方边框 } }, }, // 可选单页显示条数 pageSizes: { type: Array, default() { return [10, 20, 30] }, }, // 表格大小 size: { type: String, default: 'default', }, // 表格大小,默认,small,mini等,与el-table条件相同 }) const emit = defineEmits(['change', 'selectionChange', 'rowClick']) // -------定义数据-------------- interface columnsCheckInfo { text: string show: boolean } const columnsChecked: Ref<columnsCheckInfo[]> = ref([]) // 初始化列显示状态 function initColumnsState() { columnsChecked.value = [] for (const column of props.columns) { columnsChecked.value.push({ text: column.text, show: !!column.show }) } } defineExpose({ initColumnsState, }) // 最终展示列 const columnsFiltered: Ref<TableColumn[]> = ref([]) // 切换列 function changeColumns() { columnsFiltered.value = [] for (const i in props.columns) { if (columnsChecked.value[i].show === true) { columnsFiltered.value.push(props.columns[i]) } } } // 计算索引值方法 function indexMethod(index: number) { return props.query.limit * (props.query.offset - 1) + index + 1 } // 刷新 function refresh() { emit('change') } // 改变页容量 function handleSizeChange(val: number) { emit('change', { size: val }) } // 改变当前页 function handleCurrentChange(val: number) { emit('change', { page: val }) } // 多选选中结果 function selectionChange(selection: []) { emit('selectionChange', selection) } // 点击行 function rowClick(row: object, column?: any, event?: any) { emit('rowClick', row) } // 监听columns watch(props.columns, (val) => { initColumnsState() changeColumns() }) onBeforeMount(() => { initColumnsState() changeColumns() }) </script> <template> <div class="normal-table"> <el-table id="print" ref="table" v-loading="loading" :data="data" height="height" :size="size" :border="false" style="width: 100%;"> <slot name="preColumns" /> <el-table-column v-for="column of columns" :key="column.value" :label="column.text" :prop="column.value" :width="column.width" :align="column.align" :show-overflow-tooltip="column.showOverflow ? column.showOverflow : true" /> <slot name="columns" /> </el-table> <div v-if="props.pagination" style="width: 100%;margin-top: 10px;"> <el-pagination :current-page="props.query.offset" :page-sizes="props.pageSizes" :page-size="props.query.limit" :total="props.total" layout="total, sizes, prev, pager, next" hide-on-single-page @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </div> </template> <style lang="scss" scoped> .normal-table { width: 100%; } </style>