pc_vue_admin/src/components/DynamicTable/index.vue

145 lines
3.3 KiB
Vue
Raw Normal View History

2024-07-27 05:28:17 +00:00
<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>