效果图
Table组件
<template>
<el-table :data="tableData" style="width: 80%" v-bind="{ border: true }">
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" label="序号" width="100" fixed="left" align="center">
<template #default="{ $index }">
<i>{{ $index + 1 }}</i>
</template>
</el-table-column>
<el-table-column
v-for="col in option"
:key="col.prop"
:label="col.label"
:prop="col.prop"
:width="col.width"
:align="col.align"
v-bind="{ ...col.attrs }"
>
<template #header>
<!-- <span v-if="col.editable"><button>可编辑</button></span> -->
<span>{{ col.label }}</span>
</template>
<template #default="{ row, $index }" v-if="col.slot">
<slot :name="col.slot" :row="row" :index="$index"></slot>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { TableOption, TableData } from './tableData'
type Props = {
option: Array<TableOption>
tableData: Array<TableData>
}
const props = defineProps<Props>()
watch(props.tableData, (newVal, oldVal) => {
console.log(newVal, oldVal)
})
</script>
<style></style>
其中表格的勾选列和序号列也可以添加v-if来控制隐藏
Table的类型接口和列
export interface TableOption {
// 字段名称
prop?: string
// 表头
label: string
// 对应列的宽度
width?: string | number
// 对齐方式
align?: 'left' | 'center' | 'right'
// 自定义列模板的插槽名
slot?: string
// 是否是操作项
action?: boolean
// 是否可以编辑
editable?: boolean
// 属性
attrs?: object
}
export interface TableData {
date?: string
name?: string
address?: string
}
export interface FormData {
name?: string
}
export const option: TableOption[] = [
{
label: 'Date',
prop: 'date',
width: 200,
slot: 'dateSlot',
editable: true,
attrs: {
sortable: ''
}
},
{
label: 'Name',
prop: 'name',
slot: 'nameSlot',
attrs: {
sortable: ''
}
},
{
label: 'Address',
prop: 'address',
slot: 'addressSlot',
attrs: {
sortable: ''
}
},
{
label: 'Edit',
prop: 'edit',
slot: 'editSlot'
}
]
调用
<template>
<el-row class="mb-4">
<el-button type="primary" @click="addRow">新增行</el-button>
<el-button type="success">Success</el-button>
</el-row>
<common-table :option="option" :tableData="tableData">
<template #dateSlot="{ row }">
<div>{{ row.date }}</div>
</template>
<template #nameSlot="{ row }">
<div>
{{ row.name }}
</div>
</template>
<template #addressSlot="{ row }">
<div>
{{ row.address }}
</div>
</template>
<template #editSlot="{ row, index }">
<div>
<el-button @click="deleteRow(row, index)">删除</el-button>
<el-button @click="viewRow(row)">查看</el-button>
</div>
</template>
</common-table>
</template>
<script setup lang="ts">
import CommonTable from '../commonTable/CommonTable.vue'
import { option, TableData } from './tableData'
const tableData = reactive<TableData[]>([
{
date: '2016-05-03',
name: '1',
address: '北京'
},
{
date: '2016-05-02',
name: '2',
address: '上海'
},
{
date: '2016-05-04',
name: '3',
address: '南京'
}
])
const addRow = () => { // 添加行
const data = {
date: '22222',
name: 'asjdlasjdlad',
address: 'asjd;sad'
}
tableData.push(data)
}
const deleteRow = (row: TableData, index: number) => { // 删除行
tableData.splice(index, 1)
}
</script>
<style></style>