为数据 [{ id: null, name: '', status: true }] 生产一个vue2版本的element ui框架的列表代码 要求可以保留增删改查 函数 根据字段类型自定义合适的组件渲染
时间: 2025-07-20 18:22:39 浏览: 3
<think>我们使用Vue2和Element UI来实现一个支持增删改查的数据列表,数据结构为[{ id: null, name: '', status: true }]。
要求:根据字段类型自定义组件渲染(例如:status字段为布尔值,使用switch组件;name字段为字符串,使用input组件)
我们将使用el-table展示数据,el-form用于表单(新增/编辑),并实现CRUD操作。
步骤:
1. 定义表格列,根据字段类型自定义模板
2. 实现数据加载、新增、编辑、删除功能
3. 使用对话框进行表单操作
4. 表单验证(参考引用[4])
5. 预留API请求函数
注意:引用[1]和[2]都是关于Vue2和Element UI的增删改查实现,引用[3]是Vue3的,引用[4]提到了表单验证。
我们将按照以下结构编写代码:
- template: 包含搜索表单、操作按钮、数据表格、分页、对话框
- script: 包含数据、方法、生命周期钩子
- style: 简单样式
由于要求自定义字段渲染,我们在el-table的列中使用template,根据字段类型选择不同的组件。
具体实现如下:</think>下面是一个基于 Vue2 和 Element UI 的完整列表增删改查实现,支持字段类型自定义渲染和表单验证:
```vue
<template>
<div class="crud-container">
<!-- 搜索区域 -->
<el-form :inline="true" class="search-form">
<el-form-item label="名称">
<el-input v-model="searchQuery.name" placeholder="输入名称"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchQuery.status" placeholder="全部状态">
<el-option label="全部" value=""></el-option>
<el-option label="启用" :value="true"></el-option>
<el-option label="禁用" :value="false"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<div class="action-buttons">
<el-button type="primary" icon="el-icon-plus" @click="openCreateDialog">
新增
</el-button>
</div>
<!-- 数据表格 -->
<el-table
:data="tableData"
border
style="width: 100%"
v-loading="loading"
highlight-current-row
>
<!-- 动态列渲染 -->
<el-table-column
v-for="column in columns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
:width="column.width"
>
<template slot-scope="scope">
<!-- 根据字段类型渲染不同组件 -->
<template v-if="column.type === 'text'">
{{ scope.row[column.prop] }}
</template>
<template v-else-if="column.type === 'switch'">
<el-switch
v-model="scope.row[column.prop]"
active-color="#13ce66"
inactive-color="#ff4949"
disabled
></el-switch>
</template>
<template v-else-if="column.type === 'tag'">
<el-tag :type="scope.row[column.prop] ? 'success' : 'danger'">
{{ scope.row[column.prop] ? '启用' : '禁用' }}
</el-tag>
</template>
<template v-else-if="column.type === 'date'">
{{ formatDate(scope.row[column.prop]) }}
</template>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="200" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
@click="openEditDialog(scope.row)"
>编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handlePageChange"
:current-page="pagination.currentPage"
:page-sizes="[5, 10, 20]"
:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
></el-pagination>
<!-- 新增/编辑对话框 -->
<el-dialog
:title="dialogType === 'create' ? '新增数据' : '编辑数据'"
:visible.sync="dialogVisible"
width="600px"
>
<el-form
:model="formData"
:rules="formRules"
ref="formRef"
label-width="100px"
>
<!-- 动态表单字段 -->
<el-form-item
v-for="field in formFields"
:key="field.prop"
:label="field.label"
:prop="field.prop"
>
<!-- 文本输入框 -->
<el-input
v-if="field.type === 'text'"
v-model="formData[field.prop]"
:placeholder="`请输入${field.label}`"
></el-input>
<!-- 开关 -->
<el-switch
v-else-if="field.type === 'switch'"
v-model="formData[field.prop]"
active-text="启用"
inactive-text="禁用"
></el-switch>
<!-- 下拉选择 -->
<el-select
v-else-if="field.type === 'select'"
v-model="formData[field.prop]"
:placeholder="`请选择${field.label}`"
style="width: 100%"
>
<el-option
v-for="option in field.options"
:key="option.value"
:label="option.label"
:value="option.value"
></el-option>
</el-select>
<!-- 日期选择 -->
<el-date-picker
v-else-if="field.type === 'date'"
v-model="formData[field.prop]"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button
type="primary"
@click="submitForm"
>确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 模拟数据生成器
const generateMockData = (count = 20) => {
const data = [];
for (let i = 1; i <= count; i++) {
data.push({
id: i,
name: `项目 ${i}`,
status: Math.random() > 0.3,
category: ['电子产品', '家居用品', '服装', '食品'][Math.floor(Math.random() * 4)],
createTime: new Date(Date.now() - Math.floor(Math.random() * 10000000000))
});
}
return data;
};
// 预留API请求函数
const api = {
// 查询数据
fetchData: (params) => {
console.log('API请求: 查询数据', params);
return new Promise(resolve => {
setTimeout(() => {
const allData = generateMockData();
const { page = 1, size = 10 } = params;
const start = (page - 1) * size;
const end = start + size;
resolve({
data: allData.slice(start, end),
total: allData.length
});
}, 500);
});
},
// 创建数据
createData: (data) => {
console.log('API请求: 创建数据', data);
return new Promise(resolve => {
setTimeout(() => {
resolve({ ...data, id: Date.now() });
}, 500);
});
},
// 更新数据
updateData: (id, data) => {
console.log('API请求: 更新数据', id, data);
return new Promise(resolve => {
setTimeout(() => {
resolve({ success: true });
}, 500);
});
},
// 删除数据
deleteData: (id) => {
console.log('API请求: 删除数据', id);
return new Promise(resolve => {
setTimeout(() => {
resolve({ success: true });
}, 500);
});
}
};
export default {
data() {
return {
// 表格列配置 - 根据类型自动渲染
columns: [
{ prop: 'id', label: 'ID', width: 100, type: 'text' },
{ prop: 'name', label: '名称', type: 'text' },
{ prop: 'status', label: '状态', width: 100, type: 'switch' },
{ prop: 'status', label: '状态标签', width: 120, type: 'tag' },
{ prop: 'category', label: '分类', type: 'text' },
{ prop: 'createTime', label: '创建时间', type: 'date' }
],
// 表单字段配置
formFields: [
{ prop: 'name', label: '名称', type: 'text' },
{ prop: 'status', label: '状态', type: 'switch' },
{
prop: 'category',
label: '分类',
type: 'select',
options: [
{ value: '电子产品', label: '电子产品' },
{ value: '家居用品', label: '家居用品' },
{ value: '服装', label: '服装' },
{ value: '食品', label: '食品' }
]
}
],
// 表格数据
tableData: [],
loading: false,
// 搜索条件
searchQuery: {
name: '',
status: ''
},
// 分页配置
pagination: {
currentPage: 1,
pageSize: 10,
total: 0
},
// 对话框控制
dialogVisible: false,
dialogType: 'create', // 'create' 或 'edit'
// 表单数据
formData: {
id: null,
name: '',
status: true,
category: '电子产品'
},
// 表单验证规则
formRules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
category: [
{ required: true, message: '请选择分类', trigger: 'change' }
]
}
};
},
mounted() {
this.fetchTableData();
},
methods: {
// 获取表格数据
async fetchTableData() {
this.loading = true;
try {
const params = {
...this.searchQuery,
page: this.pagination.currentPage,
size: this.pagination.pageSize
};
const response = await api.fetchData(params);
this.tableData = response.data;
this.pagination.total = response.total;
} catch (error) {
console.error('获取数据失败:', error);
this.$message.error('获取数据失败');
} finally {
this.loading = false;
}
},
// 格式化日期
formatDate(date) {
if (!date) return '';
return new Date(date).toLocaleDateString();
},
// 打开创建对话框
openCreateDialog() {
this.dialogType = 'create';
this.formData = {
id: null,
name: '',
status: true,
category: '电子产品'
};
this.dialogVisible = true;
// 重置表单验证
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate();
}
});
},
// 打开编辑对话框
openEditDialog(row) {
this.dialogType = 'edit';
this.formData = { ...row };
this.dialogVisible = true;
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate();
}
});
},
// 提交表单(创建/更新)
async submitForm() {
this.$refs.formRef.validate(async (valid) => {
if (!valid) return;
try {
if (this.dialogType === 'create') {
const newItem = await api.createData(this.formData);
this.tableData.unshift(newItem);
this.$message.success('创建成功');
} else {
await api.updateData(this.formData.id, this.formData);
// 更新表格数据
const index = this.tableData.findIndex(item => item.id === this.formData.id);
if (index !== -1) {
this.$set(this.tableData, index, { ...this.formData });
}
this.$message.success('更新成功');
}
this.dialogVisible = false;
} catch (error) {
console.error('操作失败:', error);
this.$message.error('操作失败');
}
});
},
// 删除数据
handleDelete(row) {
this.$confirm('确定删除该记录?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
await api.deleteData(row.id);
// 从表格中移除
this.tableData = this.tableData.filter(item => item.id !== row.id);
this.$message.success('删除成功');
} catch (error) {
console.error('删除失败:', error);
this.$message.error('删除失败');
}
}).catch(() => {});
},
// 搜索
handleSearch() {
this.pagination.currentPage = 1;
this.fetchTableData();
},
// 重置搜索
resetSearch() {
this.searchQuery = { name: '', status: '' };
this.handleSearch();
},
// 分页大小变化
handleSizeChange(size) {
this.pagination.pageSize = size;
this.fetchTableData();
},
// 页码变化
handlePageChange(page) {
this.pagination.currentPage = page;
this.fetchTableData();
}
}
};
</script>
<style scoped>
.crud-container {
padding: 20px;
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.search-form {
margin-bottom: 20px;
}
.action-buttons {
margin-bottom: 20px;
}
.el-pagination {
margin-top: 20px;
text-align: right;
}
</style>
```
### 核心功能说明
1. **动态字段渲染**:
- 表格列配置 `columns` 数组定义每列的渲染方式
- 支持多种字段类型:文本(text)、开关(switch)、标签(tag)、日期(date)
- 表单字段配置 `formFields` 定义不同字段的输入组件
2. **增删改查功能**:
- **创建**:通过对话框添加新数据
- **读取**:表格展示数据,支持分页和搜索
- **更新**:编辑现有数据行
- **删除**:带确认提示的删除操作
3. **表单验证**:
- 使用 Element UI 的表单验证规则
- 必填字段验证(参考引用[4])
- 长度限制验证
4. **API 集成**:
- 预留了完整的 CRUD API 接口
- 使用 Promise 模拟异步请求
- 实际项目中可替换为 axios 请求
### 字段类型自定义实现
```javascript
// 表格列配置示例
columns: [
{ prop: 'id', label: 'ID', type: 'text' },
{ prop: 'status', label: '状态', type: 'switch' },
{ prop: 'createTime', label: '创建时间', type: 'date' }
],
// 表单字段配置示例
formFields: [
{ prop: 'name', label: '名称', type: 'text' },
{ prop: 'status', label: '状态', type: 'switch' },
{
prop: 'category',
label: '分类',
type: 'select',
options: [
{ value: '电子产品', label: '电子产品' },
{ value: '服装', label: '服装' }
]
}
]
```
### 最佳实践建议
1. **API 集成**:
```javascript
// 实际项目中的 API 实现(使用 axios)
import axios from 'axios';
const api = {
fetchData: (params) => axios.get('/api/items', { params }),
createData: (data) => axios.post('/api/items', data),
updateData: (id, data) => axios.put(`/api/items/${id}`, data),
deleteData: (id) => axios.delete(`/api/items/${id}`)
};
```
2. **表单验证增强**:
```javascript
formRules: {
email: [
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
],
phone: [
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
]
}
```
3. **性能优化**:
- 添加防抖处理搜索输入
- 实现本地数据缓存
- 使用 keep-alive 缓存组件状态
4. **扩展功能**:
- 添加批量操作功能
- 实现 Excel 导出
- 增加列显示/隐藏控制
- 添加数据权限控制
此实现完全符合 Vue2 和 Element UI 的最佳实践,通过字段类型配置实现了灵活的组件渲染,表单验证参考了 Element UI 官方文档的实现方式(引用[4]),并提供了完整的 CRUD 功能实现[^1][^2]。
阅读全文