vue3+element-plus怎么写一个高级点的通用的crud组件
时间: 2024-05-02 15:22:16 浏览: 147
要写一个高级的通用的crud组件,可以遵循以下步骤:
1. 定义props
- columns: 列定义,包括列名称、字段、是否可编辑等信息
- data: 数据源,需要是一个数组
- editable: 是否可编辑,控制表格是否可编辑
- rowKey: 行key,用于区分每一行数据的唯一标识
- showPagination: 是否显示分页器
- pageSizes: 分页器可选的每一页条数
- pageSize: 每一页的条数
- currentPage: 当前页码
2. 定义data
- tableData: 表格数据源,需要在mounted中初始化,可以使用props中的data
- currentPage: 当前页码,需要在mounted中初始化,可以使用props中的currentPage
- total: 数据总数,需要在mounted中初始化,可以使用props中的data的长度
- pageSize: 每一页的条数,需要在mounted中初始化,可以使用props中的pageSize
3. 定义computed
- displayedData: 显示的数据,根据当前页码和每一页的条数计算得出
- displayedColumns: 显示的列,根据传入的columns和editable计算得出
4. 定义methods
- handleSizeChange: 分页器每一页条数改变时的回调函数,需要更新pageSize和total
- handleCurrentChange: 分页器当前页码改变时的回调函数,需要更新currentPage
- handleEdit: 表格中的编辑操作的回调函数,需要更新tableData中的对应数据
- handleDelete: 表格中的删除操作的回调函数,需要从tableData中删除对应数据
5. 定义template
- 使用el-table组件展示数据源
- 使用v-if控制是否显示分页器
- 使用v-for循环展示列定义中的列
- 使用v-if控制列是否可编辑
- 使用slot插槽自定义每一行的操作列
完整的代码如下:
```vue
<template>
<div>
<el-table :data="displayedData" :columns="displayedColumns">
<template #default="{row}">
<td>
<slot name="operation" :row="row"></slot>
</td>
</template>
</el-table>
<el-pagination
v-if="showPagination"
:page-sizes="pageSizes"
:page-size="pageSize"
:current-page.sync="currentPage"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
export default {
name: 'CrudTable',
props: {
columns: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
},
editable: {
type: Boolean,
default: false
},
rowKey: {
type: String,
default: 'id'
},
showPagination: {
type: Boolean,
default: true
},
pageSizes: {
type: Array,
default: () => [10, 20, 30, 40, 50]
},
pageSize: {
type: Number,
default: 10
},
currentPage: {
type: Number,
default: 1
}
},
data() {
return {
tableData: [],
currentPage: 1,
total: 0,
pageSize: 10
}
},
computed: {
displayedData() {
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
return this.tableData.slice(start, end)
},
displayedColumns() {
return this.columns.map(column => {
const newColumn = { ...column }
if (this.editable && column.editable) {
newColumn.editable = true
newColumn.scopedSlots = {
default: scope => {
return (
<el-input
v-model={scope.row[column.prop]}
size="mini"
clearable
/>
)
}
}
}
return newColumn
})
}
},
methods: {
handleSizeChange(pageSize) {
this.pageSize = pageSize
this.total = this.tableData.length
},
handleCurrentChange(currentPage) {
this.currentPage = currentPage
},
handleEdit(row) {
const index = this.tableData.findIndex(item => item[this.rowKey] === row[this.rowKey])
if (index > -1) {
this.tableData.splice(index, 1, row)
}
},
handleDelete(row) {
const index = this.tableData.findIndex(item => item[this.rowKey] === row[this.rowKey])
if (index > -1) {
this.tableData.splice(index, 1)
}
}
},
mounted() {
this.tableData = this.data
this.currentPage = this.currentPage
this.total = this.tableData.length
this.pageSize = this.pageSize
}
}
</script>
```
阅读全文