You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<script setup lang="ts"> import type { VNode } from 'vue' import { onMounted, reactive } from 'vue'
import Expand from './expand'
defineOptions({ name: 'FtTable', }) const props = withDefaults(defineProps<TableProp>(), { columns: () => [], mustInit: true, hasHeader: true, getDataFn: () => Promise.resolve([]), }) const emits = defineEmits([]) enum ColumnType { index = 'index', selection = 'selection', expand = 'expand', } interface TableColumn { title: string key: string type?: ColumnType width?: number // 列宽
fixed?: 'left' | 'right' | undefined // 是否固定列
render?: (row: any) => VNode // 内容自定义
}
interface Btn { name: string icon?: string type?: string serverUrl: string }
interface TableProp { columns: TableColumn[] getDataFn: (params: any) => Promise<any> // 表格数据的接口
mustInit?: boolean // 是否在mounted里执行getDataFn
hasHeader?: boolean btnList?: Btn[] }
// const attrs = useAttrs()
async function methodParent(fn: any) { const newFn = fn[0] === '/' ? fn.slice(1) : fn emits(newFn as never) }
onMounted(() => { if (props.mustInit) { initData() } })
const state = reactive({ loading: false, dataTotal: 0, tableData: [], })
function initData() { state.loading = true props .getDataFn({}) .then((data) => { console.log(data) state.tableData = data state.loading = false }) .finally(() => { state.loading = false }) } defineExpose({ initData, }) </script>
<template> <div v-if="hasHeader" class="header"> <div v-for="btn in btnList" :key="btn.serverUrl"> <el-button :icon="btn.icon" :type="btn.type" @click="methodParent(btn.serverUrl)"> {{ btn.name }} </el-button> </div> <div class="search"> <el-input v-prevent-keyboard> <template #suffix> <el-icon class="el-input__icon"> <search /> </el-icon> </template> </el-input> </div> </div> <el-table v-loading="state.loading" :="$attrs" :data="state.tableData" style="width: 100%" height="100%" :highlight-current-row="true" class="container-table" header-row-class-name="header-row-class" > <template v-for="(column, index) in columns" :key="column.key"> <el-table-column show-overflow-tooltip :prop="column.key" :label="column.title" :width="column.width" :type="column.type" :fixed="column.fixed" > <template v-if="column.render" #default="scope"> <Expand :column="column" :row="scope.row" :render="column.render" :index="index" /> </template> </el-table-column> </template> </el-table> </template>
<style lang="scss" scoped> .header { display: flex; justify-content: space-between; align-items: center; height: 40px; .search { width: 200px; } } :deep(.header-row-class) { th { background-color: rgba(0,0,0,0.02 ) !important; //font-weight: 500;
//border-bottom: none;
color: rgba(0, 0, 0, 0.85) } } </style>
|