145 lines
3.3 KiB
Vue
145 lines
3.3 KiB
Vue
|
<template>
|
||
|
<div class="table-wrapper">
|
||
|
<!-- 工具栏 -->
|
||
|
<div class="table-tool">
|
||
|
<a-button @click="addRow" type="primary">新增</a-button>
|
||
|
<a-button @click="addRow" type="primary">删除</a-button>
|
||
|
</div>
|
||
|
|
||
|
<!-- 表格 -->
|
||
|
<a-table
|
||
|
size="middle"
|
||
|
:dataSource="dataSource"
|
||
|
:columns="computedColumns"
|
||
|
:rowKey="rowKey"
|
||
|
@change="handleTableChange"
|
||
|
:scroll="{ x: 'max-content' }"
|
||
|
:row-selection="rowSelection"
|
||
|
>
|
||
|
<template #bodyCell="{ column, record }">
|
||
|
<template v-if="column.editable">
|
||
|
<component
|
||
|
style="width: 100%"
|
||
|
:is="getComponent(column.dataType)"
|
||
|
v-model:value="record[column.dataIndex]"
|
||
|
:options="column.options"
|
||
|
/>
|
||
|
</template>
|
||
|
<template v-else>
|
||
|
<span>{{ record[column.dataIndex] }}</span>
|
||
|
</template>
|
||
|
</template>
|
||
|
<template #actions="{ record }">
|
||
|
<a-button @click="edit(record[props.rowKey])" size="small">编辑</a-button>
|
||
|
<a-popconfirm title="确定删除吗?" @confirm="() => deleteRow(record[props.rowKey])">
|
||
|
<a-button type="danger" size="small">删除</a-button>
|
||
|
</a-popconfirm>
|
||
|
</template>
|
||
|
</a-table>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script setup>
|
||
|
import { ref, reactive, computed, defineProps } from 'vue'
|
||
|
|
||
|
// 通过 defineProps 获取外部传递的属性
|
||
|
const props = defineProps({
|
||
|
initialData: {
|
||
|
type: Array,
|
||
|
default: () => []
|
||
|
},
|
||
|
columns: {
|
||
|
type: Array,
|
||
|
default: () => []
|
||
|
},
|
||
|
rowKey: {
|
||
|
type: String,
|
||
|
default: 'key'
|
||
|
}
|
||
|
})
|
||
|
|
||
|
// 内部数据
|
||
|
const dataSource = ref([...props.initialData])
|
||
|
const editingKey = ref(null)
|
||
|
|
||
|
// 获取合适的组件
|
||
|
const getComponent = (dataType) => {
|
||
|
switch (dataType) {
|
||
|
case 'number':
|
||
|
return 'a-input-number'
|
||
|
case 'select':
|
||
|
return 'a-select'
|
||
|
default:
|
||
|
return 'a-input'
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 计算列配置
|
||
|
const computedColumns = computed(() => {
|
||
|
return props.columns.map((col) => ({
|
||
|
...col,
|
||
|
editable: col.editable
|
||
|
}))
|
||
|
})
|
||
|
|
||
|
const addRow = () => {
|
||
|
const newRow = {
|
||
|
[props.rowKey]: Date.now().toString(),
|
||
|
...props.columns.reduce((acc, col) => {
|
||
|
if (col.dataIndex) acc[col.dataIndex] = ''
|
||
|
return acc
|
||
|
}, {})
|
||
|
}
|
||
|
dataSource.value = [...dataSource.value, newRow]
|
||
|
edit(newRow[props.rowKey])
|
||
|
}
|
||
|
|
||
|
const deleteRow = (key) => {
|
||
|
dataSource.value = dataSource.value.filter((item) => item[props.rowKey] !== key)
|
||
|
}
|
||
|
|
||
|
const handleFieldChange = (key, field, value) => {
|
||
|
dataSource.value = dataSource.value.map((item) => (item[props.rowKey] === key ? { ...item, [field]: value } : item))
|
||
|
}
|
||
|
|
||
|
const isEditing = (record) => record[props.rowKey] === editingKey.value
|
||
|
|
||
|
const edit = (key) => {
|
||
|
editingKey.value = key
|
||
|
}
|
||
|
|
||
|
const save = () => {
|
||
|
editingKey.value = null
|
||
|
}
|
||
|
|
||
|
const cancel = () => {
|
||
|
editingKey.value = null
|
||
|
}
|
||
|
|
||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||
|
console.log('Table changed:', pagination, filters, sorter)
|
||
|
}
|
||
|
|
||
|
const rowSelection = {
|
||
|
onChange: (selectedRowKeys, selectedRows) => {
|
||
|
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
|
||
|
},
|
||
|
onSelect: (record, selected, selectedRows) => {
|
||
|
console.log(record, selected, selectedRows)
|
||
|
},
|
||
|
onSelectAll: (selected, selectedRows, changeRows) => {
|
||
|
console.log(selected, selectedRows, changeRows)
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style scoped>
|
||
|
.table-wrapper {
|
||
|
margin: 16px;
|
||
|
}
|
||
|
|
||
|
.table-tool {
|
||
|
margin-bottom: 16px;
|
||
|
}
|
||
|
</style>
|