使用element-plus中的ElMessage样式出错

在使用element-plus框架时,若无法显示弹出提示信息,可能是因为缺少了对应样式的引入。在main.js文件中,需导入ElMessage组件以及element-plus的主题样式文件,确保在处理异常时能正确显示通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用element-plus中没有弹出提示信息框是因为没有引入样式

在main.js中引入

//导入ElementUI的消息通知组件,下面封装全局Ajax的时候处理异常的时候需要弹出通知
import {
    ElMessage
} from 'element-plus'
import 'element-plus/theme-chalk/src/index.scss'

<think>我们将基于Vue3+Element Plus搭建一个员工管理页面,包含以下功能: 1. 员工列表分页展示(使用分页查询API) 2. 添加员工(使用新增API) 3. 编辑员工(使用修改API和根据ID查询API) 4. 删除员工(单个删除和批量删除,使用删除API) 5. 搜索员工(使用分页查询API,传入搜索条件) 页面组件结构: - 搜索表单(姓名、性别、入职日期范围) - 操作按钮(添加、批量删除) - 员工表格(多选支持) - 分页组件 - 添加/编辑员工的对话框 步骤: 1. 创建Vue组件(EmployeeManagement.vue) 2. 引入Element Plus组件(Table, Form, Pagination, Dialog等) 3. 调用之前定义的API(emp.ts) 4. 实现数据绑定和事件处理 注意:由于我们使用了TypeScript,需要定义好类型。 下面开始实现:</think># Vue3 + Element Plus 员工管理系统前端实现 下面我将基于之前定义的 `emp.ts` API,实现一个完整的员工管理前端页面,包含数据渲染、分页、搜索、添加/编辑和删除功能。 ## 完整实现代码 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>员工管理系统 - Vue3 + Element Plus</title> <!-- 引入Element Plus样式 --> <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css"> <!-- 引入Vue3和Element Plus --> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://unpkg.com/element-plus"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif; background-color: #f5f7fa; color: #333; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); padding: 20px; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #ebeef5; } .header h1 { color: #303133; font-weight: 600; } .search-form { background: #f5f7fa; padding: 20px; border-radius: 4px; margin-bottom: 20px; } .el-form-item { margin-bottom: 15px; } .operation-bar { margin: 15px 0; display: flex; justify-content: space-between; } .avatar-cell { display: flex; align-items: center; } .avatar-cell img { width: 40px; height: 40px; border-radius: 50%; margin-right: 10px; object-fit: cover; } .pagination-container { margin-top: 20px; display: flex; justify-content: flex-end; } .gender-tag { padding: 0 8px; border-radius: 4px; font-size: 12px; } .male { background-color: #ecf5ff; color: #409eff; border: 1px solid #d9ecff; } .female { background-color: #fdf6ec; color: #e6a23c; border: 1px solid #faecd8; } .salary-cell { font-weight: bold; color: #e6a23c; } .dialog-footer { display: flex; justify-content: flex-end; margin-top: 20px; } .dept-info { display: flex; align-items: center; } .dept-info span { margin-left: 8px; } </style> </head> <body> <div id="app"> <div class="container"> <!-- 头部标题 --> <div class="header"> <h1>员工管理系统</h1> <el-button type="primary" @click="handleAdd">添加员工</el-button> </div> <!-- 搜索表单 --> <el-form :model="searchForm" class="search-form" label-width="80px"> <el-row :gutter="20"> <el-col :span="6"> <el-form-item label="员工姓名"> <el-input v-model="searchForm.name" placeholder="请输入姓名" clearable /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="性别"> <el-select v-model="searchForm.gender" placeholder="请选择性别" clearable> <el-option label="男" value="男" /> <el-option label="女" value="女" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="入职日期"> <el-date-picker v-model="searchForm.date" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" clearable /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24" style="text-align: right;"> <el-button type="primary" @click="search">查询</el-button> <el-button @click="resetSearch">重置</el-button> </el-col> </el-row> </el-form> <!-- 操作栏 --> <div class="operation-bar"> <el-button type="danger" :disabled="multipleSelection.length === 0" @click="batchDelete"> 批量删除 </el-button> <el-button type="text" @click="refresh"> <el-icon><Refresh /></el-icon> 刷新 </el-button> </div> <!-- 员工表格 --> <el-table :data="employeeList" stripe border style="width: 100%" @selection-change="handleSelectionChange" v-loading="loading" > <el-table-column type="selection" width="55" align="center" /> <el-table-column label="员工ID" prop="id" width="100" align="center" /> <el-table-column label="头像" width="100" align="center"> <template #default="scope"> <div class="avatar-cell"> <img :src="scope.row.image || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'" alt="头像"> </div> </template> </el-table-column> <el-table-column label="姓名" prop="name" width="120" /> <el-table-column label="用户名" prop="username" width="120" /> <el-table-column label="性别" width="80" align="center"> <template #default="scope"> <span :class="['gender-tag', scope.row.gender === '男' ? 'male' : 'female']"> {{ scope.row.gender }} </span> </template> </el-table-column> <el-table-column label="电话" prop="phone" width="150" /> <el-table-column label="职位" prop="job" width="120" /> <el-table-column label="薪资" width="120" align="right"> <template #default="scope"> <span class="salary-cell">¥{{ scope.row.salary }}</span> </template> </el-table-column> <el-table-column label="部门" min-width="150"> <template #default="scope"> <div class="dept-info"> <el-icon><OfficeBuilding /></el-icon> <span>{{ scope.row.deptName }}</span> </div> </template> </el-table-column> <el-table-column label="入职日期" prop="entryDate" width="120" /> <el-table-column label="操作" width="200" fixed="right" align="center"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <!-- 分页组件 --> <div class="pagination-container"> <el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize" :page-sizes="[5, 10, 20, 50]" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </div> <!-- 添加/编辑员工对话框 --> <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑员工信息' : '添加新员工'" width="600px" > <el-form :model="employeeForm" label-width="100px" :rules="rules" ref="employeeFormRef"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="姓名" prop="name"> <el-input v-model="employeeForm.name" placeholder="请输入姓名" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="用户名" prop="username"> <el-input v-model="employeeForm.username" placeholder="请输入用户名" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="性别" prop="gender"> <el-select v-model="employeeForm.gender" placeholder="请选择性别"> <el-option label="男" value="男" /> <el-option label="女" value="女" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="电话" prop="phone"> <el-input v-model="employeeForm.phone" placeholder="请输入电话" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="职位" prop="job"> <el-input v-model="employeeForm.job" placeholder="请输入职位" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="薪资" prop="salary"> <el-input v-model="employeeForm.salary" placeholder="请输入薪资"> <template #prepend>¥</template> </el-input> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="入职日期" prop="entryDate"> <el-date-picker v-model="employeeForm.entryDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="部门" prop="deptId"> <el-select v-model="employeeForm.deptId" placeholder="请选择部门"> <el-option v-for="dept in departmentList" :key="dept.id" :label="dept.name" :value="dept.id" /> </el-select> </el-form-item> </el-col> </el-row> <el-form-item label="头像URL" prop="image"> <el-input v-model="employeeForm.image" placeholder="请输入头像URL" /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </div> </template> </el-dialog> </div> <script> const { createApp, ref, reactive, onMounted } = Vue; const { ElMessage, ElMessageBox, ElLoading } = ElementPlus; // 模拟API请求 const mockApi = { // 分页查询员工 pageEmpApi: (params) => { return new Promise(resolve => { setTimeout(() => { // 模拟数据 const data = []; for (let i = 1; i <= params.pageSize; i++) { const id = (params.currentPage - 1) * params.pageSize + i; data.push({ id: id, username: `user${id}`, name: `员工${id}`, gender: Math.random() > 0.5 ? '男' : '女', phone: `13800${Math.floor(100000 + Math.random() * 900000)}`, job: ['开发工程师', '产品经理', 'UI设计师', '测试工程师'][Math.floor(Math.random() * 4)], salary: Math.floor(Math.random() * 10000 + 5000), image: `https://picsum.photos/100/100?random=${id}`, entryDate: `2023-${Math.floor(Math.random() * 12) + 1}-${Math.floor(Math.random() * 28) + 1}`, deptId: Math.floor(Math.random() * 3) + 1, deptName: ['技术部', '产品部', '市场部'][Math.floor(Math.random() * 3)] }); } resolve({ code: 200, data: { total: 100, rows: data } }); }, 500); }); }, // 获取所有部门 listAllDeptApi: () => { return new Promise(resolve => { setTimeout(() => { resolve({ code: 200, data: [ { id: 1, name: '技术部' }, { id: 2, name: '产品部' }, { id: 3, name: '市场部' }, { id: 4, name: '人力资源部' } ] }); }, 300); }); }, // 添加员工 saveEmpApi: (emp) => { return new Promise(resolve => { setTimeout(() => { resolve({ code: 200, msg: '添加成功' }); }, 500); }); }, // 更新员工 updateEmpApi: (emp) => { return new Promise(resolve => { setTimeout(() => { resolve({ code: 200, msg: '更新成功' }); }, 500); }); }, // 删除员工 deleteEmpApi: (ids) => { return new Promise(resolve => { setTimeout(() => { resolve({ code: 200, msg: '删除成功' }); }, 500); }); } }; createApp({ setup() { // 员工数据 const employeeList = ref([]); const loading = ref(false); // 分页参数 const pagination = reactive({ currentPage: 1, pageSize: 10, total: 0 }); // 搜索表单 const searchForm = reactive({ name: '', gender: '', date: [] }); // 部门列表 const departmentList = ref([]); // 对话框控制 const dialogVisible = ref(false); const isEdit = ref(false); // 员工表单 const employeeForm = reactive({ id: null, username: '', name: '', gender: '', phone: '', job: '', salary: '', image: '', entryDate: '', deptId: null }); // 表单验证规则 const rules = reactive({ name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], gender: [{ required: true, message: '请选择性别', trigger: 'change' }], phone: [{ required: true, message: '请输入电话', trigger: 'blur' }], job: [{ required: true, message: '请输入职位', trigger: 'blur' }], salary: [{ required: true, message: '请输入薪资', trigger: 'blur' }], entryDate: [{ required: true, message: '请选择入职日期', trigger: 'change' }], deptId: [{ required: true, message: '请选择部门', trigger: 'change' }] }); // 多选 const multipleSelection = ref([]); // 加载员工数据 const loadEmployeeData = async () => { loading.value = true; try { // 构建查询参数 const params = { currentPage: pagination.currentPage, pageSize: pagination.pageSize, name: searchForm.name, gender: searchForm.gender, begin: searchForm.date && searchForm.date[0] || '', end: searchForm.date && searchForm.date[1] || '' }; // 调用API const response = await mockApi.pageEmpApi(params); if (response.code === 200) { employeeList.value = response.data.rows; pagination.total = response.data.total; } else { ElMessage.error('加载员工数据失败'); } } catch (error) { console.error('加载员工数据出错:', error); ElMessage.error('加载员工数据出错'); } finally { loading.value = false; } }; // 加载部门数据 const loadDepartmentData = async () => { try { const response = await mockApi.listAllDeptApi(); if (response.code === 200) { departmentList.value = response.data; } } catch (error) { console.error('加载部门数据出错:', error); } }; // 分页大小改变 const handleSizeChange = (size) => { pagination.pageSize = size; loadEmployeeData(); }; // 当前页改变 const handleCurrentChange = (page) => { pagination.currentPage = page; loadEmployeeData(); }; // 处理选择 const handleSelectionChange = (selection) => { multipleSelection.value = selection.map(item => item.id); }; // 搜索 const search = () => { pagination.currentPage = 1; loadEmployeeData(); }; // 重置搜索 const resetSearch = () => { searchForm.name = ''; searchForm.gender = ''; searchForm.date = []; search(); }; // 刷新 const refresh = () => { loadEmployeeData(); }; // 添加员工 const handleAdd = () => { isEdit.value = false; // 重置表单 Object.assign(employeeForm, { id: null, username: '', name: '', gender: '', phone: '', job: '', salary: '', image: '', entryDate: '', deptId: null }); dialogVisible.value = true; }; // 编辑员工 const handleEdit = (row) => { isEdit.value = true; // 填充表单 Object.assign(employeeForm, { id: row.id, username: row.username, name: row.name, gender: row.gender, phone: row.phone, job: row.job, salary: row.salary, image: row.image, entryDate: row.entryDate, deptId: row.deptId }); dialogVisible.value = true; }; // 删除员工 const handleDelete = (id) => { ElMessageBox.confirm('确定要删除该员工吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { const loading = ElLoading.service({ lock: true }); try { const response = await mockApi.deleteEmpApi([id]); if (response.code === 200) { ElMessage.success('删除成功'); loadEmployeeData(); } else { ElMessage.error('删除失败'); } } catch (error) { console.error('删除员工出错:', error); ElMessage.error('删除员工出错'); } finally { loading.close(); } }).catch(() => {}); }; // 批量删除 const batchDelete = () => { if (multipleSelection.value.length === 0) { ElMessage.warning('请选择要删除的员工'); return; } ElMessageBox.confirm(`确定要删除选中的${multipleSelection.value.length}个员工吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { const loading = ElLoading.service({ lock: true }); try { const response = await mockApi.deleteEmpApi(multipleSelection.value); if (response.code === 200) { ElMessage.success('批量删除成功'); loadEmployeeData(); multipleSelection.value = []; } else { ElMessage.error('批量删除失败'); } } catch (error) { console.error('批量删除出错:', error); ElMessage.error('批量删除出错'); } finally { loading.close(); } }).catch(() => {}); }; // 提交表单 const submitForm = async () => { const loading = ElLoading.service({ lock: true }); try { let response; if (isEdit.value) { // 更新员工 response = await mockApi.updateEmpApi(employeeForm); } else { // 添加员工 response = await mockApi.saveEmpApi(employeeForm); } if (response.code === 200) { ElMessage.success(response.msg); dialogVisible.value = false; loadEmployeeData(); } else { ElMessage.error('操作失败'); } } catch (error) { console.error('提交表单出错:', error); ElMessage.error('提交表单出错'); } finally { loading.close(); } }; // 初始化 onMounted(() => { loadEmployeeData(); loadDepartmentData(); }); return { employeeList, loading, pagination, searchForm, departmentList, dialogVisible, isEdit, employeeForm, rules, multipleSelection, handleSizeChange, handleCurrentChange, handleSelectionChange, search, resetSearch, refresh, handleAdd, handleEdit, handleDelete, batchDelete, submitForm }; } }).use(ElementPlus).mount('#app'); </script> </body> </html> ``` ## 功能实现详解 ### 1. 员工列表展示与分页 - 使用 `el-table` 展示员工列表 - 通过 `el-pagination` 实现分页功能 - 使用 `v-loading` 提供加载状态指示 - 调用 `pageEmpApi` API 获取分页数据 ### 2. 搜索功能 - 提供姓名、性别和入职日期范围搜索 - 搜索条件绑定到 `searchForm` 对象 - 点击查询按钮触发 `search` 方法重新加载数据 ### 3. 员工操作功能 - **添加员工**:打开表单对话框,填写员工信息后提交 - **编辑员工**:点击编辑按钮,加载员工信息到表单 - **删除员工**:单个删除或批量删除,二次确认后执行 - **刷新功能**:重新加载当前页数据 ### 4. 表单验证 - 使用 `el-form` 的 `rules` 属性定义验证规则 - 必填字段验证(姓名、用户名、性别、电话等) - 提交前自动验证表单数据 ### 5. 数据模拟 - 使用 `mockApi` 对象模拟后端API请求 - 生成随机员工数据用于演示 - 模拟API请求延迟 ### 6. 响应式设计 - 使用Element Plus的栅格系统实现响应式布局 - 表单在不同屏幕尺寸下自动调整布局 - 表格支持固定列和响应式显示 ## 页面功能亮点 1. **直观的数据展示**: - 员工头像展示 - 性别标签使用不同颜色区分 - 薪资突出显示 - 部门信息带图标展示 2. **丰富的交互体验**: - 加载状态指示 - 操作成功/失败提示 - 删除操作的二次确认 - 表单验证反馈 3. **高效的操作流程**: - 批量选择删除 - 快速搜索和重置 - 一键刷新功能 - 添加/编辑统一表单 4. **响应式设计**: - 适应不同屏幕尺寸 - 在小屏幕下自动调整布局 - 表格支持水平滚动 ## 使用说明 1. 页面加载时自动加载第一页员工数据 2. 使用顶部搜索框可以按姓名、性别和入职日期筛选员工 3. 点击"添加员工"按钮打开表单对话框 4. 点击表格行中的"编辑"按钮可以修改员工信息 5. 选择多个员工后可以使用"批量删除"按钮 6. 使用表格底部分页器可以浏览不同页的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诉衷情の麻雀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值