一、需求分析
-
页面功能
- 提供部门信息的展示功能,数据以表格形式呈现,包含序号、部门名称、最后操作时间、操作(编辑和删除)列。
- 用户可通过新增、编辑和删除功能,实现对部门数据的管理。
- 数据动态加载,支持实时更新,确保部门信息的准确性。
-
功能实现细节
- 部门展示:从后端接口获取所有部门数据并展示在表格中,支持按序号排序。
- 新增部门:点击“新增部门”按钮后,弹出表单对话框,用户输入新部门名称并保存。
- 编辑部门:支持选择部门后修改其信息,数据从后端动态加载并回显在表单中。
- 删除部门:在用户确认删除操作后,调用后端接口删除指定的部门。
- 表单校验:新增与编辑时,表单需满足字段校验规则(如必填、长度限制等)。
-
技术需求
- 使用 Vue 3 框架进行页面搭建,支持响应式设计。
- 使用 Element-Plus 组件库构建界面,简化开发流程。
二、代码解读
总体代码:
<script setup lang="ts">
import { addApi, deleteApi, getInfoApi, queryAllApi, updateApi } from '@/api/dept';
import type { DeptModel, DeptModelArray } from '@/api/model/model';
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
import { onMounted, ref } from 'vue';const deptList = ref<DeptModelArray>([])const search = async () => {const result = await queryAllApi()if (result.code) {deptList.value = result.data}
}const formLabelWidth = '140px'
const dialogFormVisible = ref<boolean>(false)
const dept = ref<DeptModel>({name: '',
})
const formValue = ref<string>('')onMounted(() => {search()
})// 添加部门逻辑
const addDept = () => {dialogFormVisible.value = true//清空公用部门数据dept.value = { name: '' }//清空表单校验resetForm(ruleFormRef.value)formValue.value = '部门管理'
}// 添加和编辑部门逻辑,根据id属性是否为空来区分是新增还是编辑
const save = async (formEl: FormInstance | undefined) => {//添加表单校验if (!formEl) returnawait formEl.validate(async (valid) => {if (valid) {//根据ID判断执行添加部门还是编辑部let result = nullif (dept.value.id) {result = await updateApi(dept.value)} else {result = await addApi(dept.value)}if (result.code) {dialogFormVisible.value = falseElMessage.success('添加成功')search()} else {ElMessage.error(result.msg)}} else {ElMessage.error('请重新输入')}})}// 编辑部门逻辑
const updateDept = async (id: number) => {dialogFormVisible.value = true//清空公用部门数据dept.value = { name: '' }//清空表单校验resetForm(ruleFormRef.value)formValue.value = '编辑部门'//查询回显const result = await getInfoApi(id)if (result.code) {dept.value = result.data}
}// 删除部门逻辑
const deleteById = (id: number) => {ElMessageBox.confirm('您确定要删除该部门吗 ?','提示',{confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',}).then(async () => {const result = await deleteApi(id)if (result.code) {ElMessage({type: 'success',message: '删除成功',})} else {ElMessage({type: 'error',message: '删除失败',})}search()}).catch(() => {ElMessage({type: 'info',message: '取消删除',})})
}//表单校验功能interface RuleForm {name: string
}const ruleFormRef = ref<FormInstance>()//定义表单引用对象--与表单ref属性绑定const rules = ref<FormRules<RuleForm>>({name: [{ required: true, message: '部门名称为必填项', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称长度必须在2-10位', trigger: 'blur' },]
})const resetForm = (formEl: FormInstance | undefined) => {if (!formEl) returnformEl.resetFields()
}</script><!-- 部门表格 -->
<template><h1>部门管理</h1> <br><el-button type="primary" @click="addDept">+ 新增部门</el-button> <br><br><el-table :data="deptList" border style="width: 100%"><el-table-column type="index" label="序号" width="100" align="center" /><el-table-column prop="name" label="部门名称" width="200" align="center" /><el-table-column prop="updateTime" label="最后操作时间" width="250" align="center" /><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="success" @click="updateDept(scope.row.id)">编辑</el-button><el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button></template></el-table-column></el-table><!-- 新增与编辑部门表单 --><el-dialog v-model="dialogFormVisible" :title=formValue width="500"><el-form :model="dept" :rules="rules" ref="ruleFormRef"><el-form-item label="部门名称" :label-width="formLabelWidth" prop="name"><el-input v-model="dept.name" autocomplete="off" /></el-form-item></el-form><template #footer><div class="dialog-footer">{{ dept }}<el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="save(ruleFormRef)">确认</el-button></div></template></el-dialog></template><style scoped></style>
总体异步请求封装:
//编写与服务器进行异步交互的代码
import request from '@/utils/request'
import type { DeptModel, ResultModel } from './model/model'//1. 查询所有部门 ---> 第二个泛型, 指服务器响应的数据类型
export const queryAllApi = () => request.get<any, ResultModel>('/depts')//2. 新增部门 ---> 第二个泛型, 指服务器响应的数据类型
export const addApi = (dept:DeptModel) => request.post<any, ResultModel>('/depts', dept)//3. 根据id查询 ---> 第二个泛型, 指服务器响应的数据类型
export const getInfoApi = (id:number) => request.get<any, ResultModel>(`/depts/${id}`)//4. 修改部门 ---> 第二个泛型, 指服务器响应的数据类型
export const updateApi = (dept:DeptModel) => request.put<any, ResultModel>(`/depts`, dept)//5. 删除部门 ---> 第二个泛型, 指服务器响应的数据类型
export const deleteApi = (id:number) => request.delete<any, ResultModel>(`/depts?id=${id}`)
页面初始化与数据加载
定义search
方法:
const search = async () => {const result = await queryAllApi();if (result.code) {deptList.value = result.data;}
};
- 通过
queryAllApi
接口从后端获取部门数据,并赋值给响应式变量deptList
。 - 判断接口返回值的
code
是否为成功状态以更新数据。
页面加载时调用:
onMounted(() => {search();
});
利用 Vue 生命周期的onMounted
钩子,在页面加载时自动加载部门数据
新增与编辑功能
弹出表单的初始化
1. 新增部门初始化逻辑:
const addDept = () => {dialogFormVisible.value = true;dept.value = { name: '' }; // 清空部门数据resetForm(ruleFormRef.value); // 重置表单校验formValue.value = '新增部门';
};
- 弹出新增部门的对话框。
- 清空
dept
对象,重置表单内容。
2. 编辑部门初始化逻辑:
const updateDept = async (id: number) => {dialogFormVisible.value = true;dept.value = { name: '' }; // 清空部门数据resetForm(ruleFormRef.value); // 重置表单校验formValue.value = '编辑部门';const result = await getInfoApi(id); // 获取部门详细信息if (result.code) {dept.value = result.data; // 回显数据}
};
- 弹出编辑部门的对话框。
- 根据部门ID调用接口获取详情并回显。
保存部门数据
// 添加和编辑部门逻辑,根据id属性是否为空来区分是新增还是编辑
const save = async (formEl: FormInstance | undefined) => {//添加表单校验if (!formEl) returnawait formEl.validate(async (valid) => {if (valid) {//根据ID判断执行添加部门还是编辑部let result = nullif (dept.value.id) {result = await updateApi(dept.value)} else {result = await addApi(dept.value)}if (result.code) {dialogFormVisible.value = falseElMessage.success('添加成功')search()} else {ElMessage.error(result.msg)}} else {ElMessage.error('请重新输入')}})}
- 检查表单校验是否通过。
- 根据
dept.value.id
判断操作类型:- 新增操作:调用
addApi
接口。 - 编辑操作:调用
updateApi
接口。
- 新增操作:调用
- 操作成功后刷新数据列表。
删除功能
const deleteById = (id: number) => {ElMessageBox.confirm('您确定要删除该部门吗 ?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',}).then(async () => {const result = await deleteApi(id);if (result.code) {ElMessage.success('删除成功');search(); // 刷新数据} else {ElMessage.error('删除失败');}});
};
- 弹出确认框,用户点击“确定”后执行删除。
- 调用
deleteApi
接口删除部门数据。 - 删除成功后刷新页面数据。
表单校验
定义校验规则:
const rules = ref<FormRules<RuleForm>>({name: [{ required: true, message: '部门名称为必填项', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称长度必须在2-10位', trigger: 'blur' },],
});
- 部门名称为必填项。
- 限制名称长度在2到10个字符。
重置表单校验:
const resetForm = (formEl: FormInstance | undefined) => {if (!formEl) return;formEl.resetFields();
};
- 重置表单内容与校验状态。
页面模板与样式
部门表格
<el-table :data="deptList" border style="width: 100%"><el-table-column type="index" label="序号" width="100" align="center" /><el-table-column prop="name" label="部门名称" width="200" align="center" /><el-table-column prop="updateTime" label="最后操作时间" width="250" align="center" /><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="success" @click="updateDept(scope.row.id)">编辑</el-button><el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button></template></el-table-column>
</el-table>
- 表格展示部门数据,包含序号、名称、时间及操作列。
- 操作列内嵌“编辑”和“删除”按钮。
新增与编辑部门表单模板
<!-- 新增与编辑部门表单 -->
<el-dialog v-model="dialogFormVisible" :title=formValue width="500"><el-form :model="dept" :rules="rules" ref="ruleFormRef"><el-form-item label="部门名称" :label-width="formLabelWidth" prop="name"><el-input v-model="dept.name" autocomplete="off" /></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="save(ruleFormRef)">确认</el-button></div></template>
</el-dialog>
1. 使用el-dialog
构建弹窗
-
属性
v-model="dialogFormVisible"
:控制对话框的显示与隐藏。 -
属性
:title="formValue"
:动态设置弹窗标题(“新增部门”或“编辑部门”)。 -
属性
width="500"
:设置弹窗宽度为500px。
2. 表单部分:使用el-form
组件
-
属性
:model="dept"
:绑定表单数据模型dept
。-
dept
是响应式变量,数据结构为DeptModel
类型,包含id
和name
字段。
-
-
属性
:rules="rules"
:绑定表单校验规则,确保数据完整性。 -
属性
ref="ruleFormRef"
:定义表单引用,用于后续的校验操作。
3. 表单项el-form-item
-
属性
label="部门名称"
:定义表单字段标签。 -
属性
:label-width="formLabelWidth"
:设置标签宽度,取值为formLabelWidth
变量(默认值为140px
)。 -
属性
prop="name"
:绑定校验规则name
,用于触发校验。
4. 输入框el-input
-
属性
v-model="dept.name"
:双向绑定dept
对象的name
字段,用于存储用户输入。
底部按钮区域(Slot: footer)
取消按钮:
<el-button @click="dialogFormVisible = false">取消</el-button>
点击按钮时,将dialogFormVisible
设为false
以关闭弹窗。
确认按钮:
<el-button type="primary" @click="save(ruleFormRef)">确认</el-button>
点击按钮时,调用save()
方法提交表单数据。
三、总结
- 使用响应式数据结合
Element-Plus
组件,构建了直观、友好的用户界面。 - 数据接口的封装简化了与后端的交互,减少冗余代码。
- 表单校验与弹框功能有效提升了用户操作体验。