封装一个el-table组件:子组件仅负责事件触发,业务逻辑(如API调用、状态更新)由父组件实现
<template>
<el-table
:data="tableData"
border
stripe
style="width: 100%; height: calc(100% - 32px);"
class="data-table"
>
<!-- 设备类型列 -->
<el-table-column prop="name" label="设备类型" width="150">
<template #default="{ row }">
<el-text>{{ row.name }}</el-text>
</template>
</el-table-column>
<!-- 价格列 -->
<el-table-column prop="price" label="价格" width="100">
<template #default="{ row }">
<el-text>{{ row.price }}</el-text>
</template>
</el-table-column>
<!-- 电脑SN列 -->
<el-table-column prop="sn" label="电脑SN" width="220">
<template #default="{ row }">
<el-text type="info" copyable>{{ row.sn }}</el-text>
</template>
</el-table-column>
<!-- 供应商列(带筛选) -->
<el-table-column
prop="supplier"
label="供应商"
width="120"
:filters="filters.supplier"
:filter-method="filterData"
>
<template #default="{ row }">
<el-tag effect="plain" :type="supplierTagType[row.supplier]">
{{ row.supplier }}
</el-tag>
</template>
</el-table-column>
<!-- 入库日期列 -->
<el-table-column prop="storageDate" label="入库日期" width="150">
<template #default="{ row }">
{{ formatDate(row.storageDate) }}
</template>
</el-table-column>
<!-- 地区列(带筛选) -->
<el-table-column
prop="region"
label="地区"
width="100"
:filters="filters.region"
:filter-method="filterData"
>
<template #default="{ row }">
<el-tag effect="plain">{{ row.region }}</el-tag>
</template>
</el-table-column>
<!-- 备注列 -->
<el-table-column prop="remark" label="备注" min-width="200"></el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button type="primary" size="small" @click="handleEdit(row)">
<el-icon><Edit /></el-icon>修改
</el-button>
<el-button type="danger" size="small" @click="handleDelete(row)">
<el-icon><Delete /></el-icon>删除
</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
import { Edit, Delete } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
const props = defineProps({
tableData: {
type: Array,
required: true,
default: () => []
},
filters: {
type: Object,
required: true,
default: () => ({})
},
supplierTagType: {
type: Object,
required: true,
default: () => ({})
}
})
const emit = defineEmits(['edit', 'delete'])
// 日期格式化
function formatDate(date) {
return date ? dayjs(date).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')
}
// 筛选方法
const filterData = (value, row, column) => {
return row[column.property] === value
}
// 操作事件转发
const handleEdit = (row) => {
emit('edit', row)
}
const handleDelete = (row) => {
emit('delete', row)
}
</script>
<style scoped>
.data-table {
margin-top: 20px;
}
</style>
在父组件中使用这个组件,并给他传值:
<BillTable
:table-data="tableData"
:filters="filters"
:supplier-tag-type="supplierTagType"
@edit="handleEdit"
@delete="handleDelete"
/>
代码解释:
通过:data="tableData"将数组数据与表格绑定
通过:filters和:filter-method实现筛选功能,数据匹配逻辑在filterData方法中定义
声明组件props的语法,通过defineProps函数定义组件需要接收的三个属性
emit方法属于Vue 3的setup语法糖,通过defineEmits声明后使用,用于子组件向父组件跨层级通信