项目地址Admin/zwy_manager_up_v1
1.前端项目
1.1项目创建
1.1.1使用cmd创建vue项目
在文件资源管理器中打开你想创建位置路径
npm create vue@latest
选择只选择Route
依次执行以下命令
访问搭建好的vue项目
1.1.2瘦身vue项目
idea打开该项目,项目原始结构如下
瘦身后的项目结构
修改3个文件添加1个文件
名称:App.vue
位置:src/App.vue
<template>
<RouterView/>
</template>
名称:main.js
位置:src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
名称:HelloWorld.vue
位置:src/views/HelloWorld.vue
<template>
<div>
<h1>Hello World</h1>
</div>
</template>
<script setup>
</script>
名称:index.js
位置:src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'hello',
component: () => import('../views/HelloWorld.vue'),
},
],
})
export default router
1.1.3集成element-plus
下载element-plus依赖
npm install element-plus@
package-lock.json或package.json或node_modules查看是否引入
配置element-plus
位置:src/main.js
名称:main.js
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
测试element-plus是否配置好
新建视图
位置:src/views/Button.vue
名称:Button.vue
<template>
<div>
<el-button type="primary" @click="handleClick">按钮</el-button>
</div>
</template>
<script setup>
</script>
添加路由
位置:src/router/index.js
名称:index.js
{
path: '/button',
name: 'button',
component: () => import('../views/Button.vue'),
}
访问该视图
1.2视图搭建
一共有4个,404.vue,manager.vue,employeeOp.vue,home.vue
其中manager.vue(employeeOp.vue,home.vue) 是嵌套关系
404.vue是路由守卫
1.2.1 全局映入icon
位置:src/main.js
名称:main.js
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
1.2.2导入所需要的图片和样式
位置:src/assets/global.css
名称:global.css
.card {
margin-top: 20px;
margin-left: 10px;
padding: 10px;
width: calc(100% - 40px);
background-color: #ffffff;
border: 1px solid #e4e7ed;
border-radius: 4px;
color: #303133;
}
位置:src/assets/img.png
名称:img.png
位置:/assets/404.png
名称:404.png
1.2.3视图文件编写
位置:src/view/employeeDataOp.vue
名称:employeeDataOp.vue
<template>
<div >
<!-- 第一项 搜索框和重置按钮-->
<div class="card">
<el-input v-model="searchName" placeholder="请输入员工姓名" style="width: 200px;margin-right: 5px;" suffix-icon="Search"/>
<el-button type="primary">搜索</el-button>
<el-button type="warning">重置</el-button>
</div>
<!-- 第二项 常用操作 批量删除 添加员工-->
<div class="card">
<el-button type="primary">新建员工</el-button>
<el-button type="danger">批量删除</el-button>
</div>
<!-- 第三项 员工数据表格-->
<div class="card">
<el-table :data = "data.tableData" height="400" style="width: 100%;border: #7a7575 solid 1px">
<el-table-column prop="id" label="编号" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="gender" label="性别" />
<el-table-column prop="title" label="职位" />
<el-table-column prop="birthday" label="出生日期"/>
</el-table>
</div>
<!-- 第四项 分页组件-->
<div class="card">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
/>
</div>
</div>
</template>
<script setup>
import {reactive} from "vue";
const data = reactive({
tableData: [
{
id:1,
name:'张三',
gender:'男',
title:'高级工程师',
birthday:'1985-01-01'
},
],
})
</script>
位置:src/veiws/home.vue
名称:home.vue
<template>
<div>
员工管理系统首页
</div>
</template>
<script setup>
</script>
位置:src/veiws/manager.vue
名称:manager.vue
<template>
<div>
<!-- 顶部信息栏(logo 系统名 用户头像 用户名)开始 -->
<div style="height: 40px;background-color: aqua;display:flex;align-items:center;
">
<img src="../assets/img.png" style="width: 40px;margin-left: 20px">
<span style="margin-left: 10px;font-size: 20px;font-family: 新宋体;color: white">员工管理系统</span>
<div style="flex:1"></div>
<el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"/>
<span style="margin-left: 10px;margin-right:10px;font-size: 20px;font-family: 新宋体;color: white">泳</span>
</div>
<!-- 顶部信息栏(logo 系统名 用户头像 用户名)结束 -->
<!-- body部分开始-->
<div style="display: flex">
<!-- 左边导航栏开始-->
<div style="width: 140px;height: calc(100vh - 40px);border-right: #cdcdcd solid 1px">
<el-menu
router>
<el-menu-item index="/manager/home" >
<el-icon>
<HomeFilled />
</el-icon>
<span>首页</span>
</el-menu-item>
<el-menu-item index="/manager/employeeDataOp">
<el-icon><User /></el-icon>
<span>员工管理</span>
</el-menu-item>
</el-menu>
</div>
<!-- 左边导航栏结束-->
<!-- 右边数据域开始-->
<div style="width: calc(100% - 140px)">
<RouterView/>
</div>
<!-- 右边数据域结束-->
</div>
<!-- body部分结束-->
</div>
</template>
<script setup>
</script>
位置:src/view/404.vue
名称:404.vue
<template>
<div class="card" style="display:flex;align-items:center;">
<img src="@/assets/404.png" style="width: 100%;">
</div>
<div style="margin-top: 20px;">
<div style="text-align: center;">
<el-button type="primary" @click="backLatestPage">返回上一页</el-button>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const backLatestPage = () => {
router.go(-1)
}
</script>
1.2.4路由修改
位置:src/router/index.js
名称:index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'hello',
component: () => import('../views/HelloWorld.vue'),
},
{
path: '/button',
name: 'button',
component: () => import('../views/Button.vue'),
},
{
path:'/manager',
name:'manager',
component:()=>import('../views/Manager.vue'),
children:[
{
path:'/manager/employeeDataOp',
name:'employeeDataOp',
meta:{title:'员工数据操作'},
component:()=>import('../views/employeeDataOp.vue')
},
{
path:'/manager/home',
name:'home',
meta:{title:'首页'},
component:()=>import('../views/home.vue')
}
]
},
{
path:'/404',
name:'404',
meta:{title:'404'},
component:()=>import('../views/404.vue')
},
{
path:'/:pathMatch(.*)*',
redirect:'/404',
}
],
})
router.beforeEach((to,from,next)=>{
document.title=to.meta.title;
next()
})
export default router
1.2.4静态界面展示
1.3接口调用
1.3.1安装axios(发请求的工具)
npm install axios@latest
1.3.2编写request.js文件(处理请求)
位置:src/utils/request.js
const request = axios.create({
baseURL:'http://localhost:9999',//后台接口地址
timeout:5000 //请求超时设置
})
//request 拦截器
// 可以自请求发送前对请求做一些处理
request.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
return config
},error => {
return Promise.reject(error)
});
//可以在接口响应后统一处理结果
request.interceptors.response.use(
response =>{
let res = response.data;
// 兼容服务器端返回的字符串数据
if(typeof res === 'string') {
res = res ? JSON.parse(res) : res
}
return res;
},
error => {
if(error.response.status === 404){
ElMessage.error('服务器未找到该接口')
}else if(error.response.status === 500){
ElMessage.error('服务器内部错误')
}else{
console.error(error.message)
}
return Promise.reject(error)
}
)
export default request
1.3.3修改employeeDataOp.vue
位置:src/views/employeeDataOp.vue
<template>
<div >
<!-- 第一项 搜索框和重置按钮-->
<div class="card">
<el-input v-model="data.searchName" placeholder="请输入员工姓名" style="width: 200px;margin-right: 5px;" suffix-icon="Search"/>
<el-button type="primary" @click="loadData()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
</div>
<!-- 第二项 常用操作 批量删除 添加员工-->
<div class="card">
<el-button type="primary" @click="switchAddDialog">新建员工</el-button>
<el-button type="danger" @click="deleteBatchMessageBox">批量删除</el-button>
</div>
<!-- 第三项 员工数据表格-->
<div class="card">
<el-table @selectionChange="handleSelectionChange" :data = "data.tableData" height="400" style="width: 100%;border: #7a7575 solid 1px">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="编号" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="gender" label="性别" />
<el-table-column prop="title" label="职位" />
<el-table-column prop="birthday" label="出生日期"/>
<el-table-column fixed="right" label="操作" width="120">
<template #default="scope">
<el-button type="primary" @click="editRow(scope.row)" circle>
<el-icon><Edit /></el-icon>
</el-button>
<el-button type="danger" @click="deleteMessageBox(scope.row)" circle>
<el-icon><Delete /></el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 第四项 分页组件-->
<div class="card">
<el-pagination
v-model:current-page="data.currentPage"
v-model:page-size="data.pageSize"
@current-change="loadData"
@size-change="loadData"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
v-model:total="data.total"
/>
</div>
<el-dialog
v-model="data.AddDialogVisible"
title="新建员工"
width="300"
align-center
>
<el-input v-model="data.employee.name" style="width: 240px;margin-bottom: 20px;" placeholder="请输入名称"></el-input>
<el-radio-group v-model="data.employee.gender" style="width: 240px;margin-bottom: 20px;">
<el-radio value="男" size="large" border>男</el-radio>
<el-radio value="女" size="large" border>女</el-radio>
</el-radio-group>
<el-input v-model="data.employee.title" style="width: 240px;margin-bottom: 20px;" placeholder="请输入职称"></el-input>
<el-date-picker
v-model="data.employee.birthday"
type="date"
placeholder="选择出生日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="switchAddDialog">取消</el-button>
<el-button type="primary" @click="save()">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {reactive,ref} from "vue";
import request from "@/utils/request.js";
import {ElMessage,ElMessageBox} from "element-plus";
const res = ref();
const data = reactive({
AddDialogVisible:false,
tableData: [
],
currentPage:1,
pageSize:5,
searchName:'',
employee:{
id:0,
name:'',
gender:'',
title:'',
birthday:''
},
ids:[]
})
const loadData = () => {
const loadAll = () =>{
request.get('employee/selectPage', {
params: {
pageNum: data.currentPage,
pageSize: data.pageSize,
}
}).then(res=> {
data.tableData = res.data.list;
data.total = res.data.total;
console.log(res.data.list)
})
}
const loadByName = () =>{
request.post('employee/findByName',{
name:data.searchName,
},{ params: {
pageNum: data.currentPage,
pageSize: data.pageSize,
}}).then(res=>{
data.tableData = res.data.list;
data.total = res.data.total;
console.log(res.data.list)
})
}
data.searchName ? loadByName() :loadAll()
}
loadData();
const reset = () =>{
data.searchName = '';
loadData();
}
const switchAddDialog = () =>{
data.AddDialogVisible = data.AddDialogVisible ? false : true;
}
const editRow = (row) =>{
data.employee = row;
switchAddDialog();
//深拷贝,解决就算取消修改,数据还是被修改了的问题
data.employee = JSON.parse(JSON.stringify(row));
}
const save = () =>{
const update = () =>{
request.put('employee/modify',data.employee).then(res=>{
console.log(res);
if(res.code === '200'){
ElMessage.success('添加成功');
loadData();
switchAddDialog();
}else {
ElMessage.error(res.code + '/n' + res.msg);
}
})
}
const add = () =>{
request.post('employee/add',data.employee).then(res=>{
console.log(res);
if(res.code === '200'){
ElMessage.success('添加成功');
loadData();
switchAddDialog();
}else {
ElMessage.error(res.code + '/n' + res.msg);
}
})
}
data.employee.id != 0 ? update() : add();
}
const deleteOne = (row) =>{
request.delete(`employee/deleteById/${row.id}`).then(res=>{
if(res.code === '200'){
ElMessage.success('删除成功');
loadData();
}else {
ElMessage.error(res.code + '/n' + res.msg);
}
})
}
const handleSelectionChange = (rows) =>{
data.ids = rows.map(row => row.id);
console.log(data.ids);
}
const deleteBatch = () =>{
request.delete(`employee/deleteBatch`,{data:data.ids}).then(res=>{
if(res.code === '200'){
ElMessage.success('批量删除成功');
loadData();
}else {
ElMessage.error(res.code + '/n' + res.msg);
}
})
}
const deleteMessageBox = (row) =>{
ElMessageBox.confirm('此操作将永久删除该信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'danger',
}).then(() => {
deleteOne(row);
}).catch(() => {
ElMessage({
type: 'info',
message: '已取消删除',
});
});
}
const deleteBatchMessageBox = () =>{
if(data.ids.length === 0){
ElMessage.error('请选择要删除的数据');
return;
}
ElMessageBox.confirm('此操作将永久删除该信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'danger',
}).then(() => {
deleteBatch();
}).catch(() => {
ElMessage({
type: 'info',
message: '已取消删除',
});
});
}
</script>
我来解释也哈这个视图,
静态内容方面
分为四个部分对应代码四个<div>
第一个是搜索框
第二个是一些基础操作
第三个是表格
第四个是分页组件
还有一个对话框作用是添加或修改员工信息点击新建按钮这个对话框显示对应代码<el_dialog>标签
还有一个消息框当,进行删除操作时候提供一个缓冲,以免误删对应const deleteMassageBox,deleteBatchMassageBox.