一、开发模式主流前后端分离1、什么是前后端分离开发模式?前后端开发人员独立开发独立部署2、需求的开发流程需求分析-接口定义-前后端并行开发-测试-前后端联调测试二、整体布局1、准备工作在vite.config.js目录中alias: { // 将 /xxx 映射到 src/xxx相当于为src目录起别名 : fileURLToPath(new URL(./src, import.meta.url))src/view/layout/index.vue文件下!-- 左侧菜单 -- template el-container el-aside width200px classaside el-menu el-sub-menu index1 template #title el-iconHomeFilled //el-icon班级学员管理 /template el-menu-item index1-1 el-iconHelpFilled //el-icon班级管理 /el-menu-item el-menu-item index1-2 el-iconUserFilled //el-icon学员管理 /el-menu-item /el-sub-menu /el-menu /el-aside el-container template在main.js中注册icon图标// 引入icon import * as ElementPlusIconsVue from element-plus/icons-vue; // 注册icon图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component); }2、动态菜单1VueRouterVue RouterVue Router | Vue.js 的官方路由VueRouterVue的官方路由。为Vue提供富有表现力、可配置的、方便的路由。Vue中的路由路径与组件的对应关系。组成Router实例路由实例基于createRouter函数创建维护了应用的路由信息。router-link路由链接组件浏览器会解析成a。router-view动态视图组件用来渲染展示与路由路径对应的组件。src/view/layout/index.vue文件下router-link路由链接组件环绕首页菜单并指定访问路径!-- 首页菜单 -- router-link to/index el-menu-item index/index el-iconPromotion //el-icon 首页 /el-menu-item /router-link或者只需在他上级加上 router即可以el-menu-item作为路径跳转el-menu router//默认为true !-- 首页菜单 -- el-menu-item index/index el-iconPromotion //el-icon 首页 /el-menu-itemsrc/router/index.js下创建Router实例import { createRouter, createWebHistory } from vue-router; import IndexView from /views/index/index.vue; import ClazzView from /views/clazz/index.vue; import DeptView from /views/dept/index.vue; import EmpView from /views/emp/index.vue; import LogView from /views/log/index.vue; import StuView from /views/stu/index.vue; import EmpReportView from /views/report/emp/index.vue; import StuReportView from /views/report/stu/index.vue; import LayoutView from /views/layout/index.vue; import LoginView from /views/login/index.vue; const router createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: /index, name: index, component: IndexView }, { path: /clazz, name: clazz, component: ClazzView }, { path: /stu, name: stu, component: StuView }, { path: /dept, name: dept, component: DeptView }, { path: /emp, name: emp, component: EmpView }, { path: /log, name: log, component: LogView }, { path: /empReport, name: empReport, component: EmpReportView }, { path: /stuReport, name: stuReport, component: StuReportView }, { path: /login, name: index, component: LoginView }, ], }); export default router;访问地址就会访问路由展示组件处1.Vue的路由指的是什么VueRouter是vue官方的路由描述的是路径与组件的对应关系2、VueRouter中的三个核心组成部分router实例维护了应用的路由信息routesrouter-link路由链接组件router-view动态视图组件2VueRouter嵌套路由src/router/index.js这样写import { createRouter, createWebHistory } from vue-router; import IndexView from /views/index/index.vue; import ClazzView from /views/clazz/index.vue; import DeptView from /views/dept/index.vue; import EmpView from /views/emp/index.vue; import LogView from /views/log/index.vue; import StuView from /views/stu/index.vue; import EmpReportView from /views/report/emp/index.vue; import StuReportView from /views/report/stu/index.vue; import LayoutView from /views/layout/index.vue; import LoginView from /views/login/index.vue; const router createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: /, name: , component: LayoutView, redirect: /index, //重定向 children: [ { path: /index, name: index, component: IndexView }, { path: /clazz, name: clazz, component: ClazzView }, { path: /stu, name: stu, component: StuView }, { path: /dept, name: dept, component: DeptView }, { path: /emp, name: emp, component: EmpView }, { path: /log, name: log, component: LogView }, { path: /empReport, name: empReport, component: EmpReportView }, { path: /stuReport, name: stuReport, component: StuReportView }, ], }, { path: /login, name: login, component: LoginView }, ], }); export default router;三、部门管理1、列表查询1页面布局基础页面布局在src/views/dept/index.vuescript setup import { ref } from vue; const tableData ref([ { id: 1, name: 学工部, createTime: 2022-09-01T23:06:29, updateTime: 2022-09-01T23:06:29, }, ]); /script template h1部门管理/h1 div classcontainer el-button typeprimary 新增部门/el-button /div div classcontainer el-table :datatableData border stylewidth: 100% el-table-column propid label序号 width100 aligncenter/ el-table-column propname label部门名称 width260 aligncenter/ el-table-column propupdateTime label最后操作时间 width300 aligncenter/ el-table-column propaddress label操作 aligncenter template #defaultscope el-button typeprimary sizesmallel-iconEditPen //el-icon编辑/el-button el-button typedanger sizesmallel-iconDeleteFilled //el-icon删除/el-button /template /el-table-column /el-table /div /template style scoped .container { margin: 10px 0px; } /style2加载数据script setup import { ref, onMounted } from vue; import axios from axios; //钩子函数 页面加载完毕后调用钩子函数加载其他函数 onMounted(() { search(); }); //查询 const search async () { const result await axios.get( https://apifoxmock.com/m1/3128855-1224313-default/depts ); if (result.data.code) { //JS隐式类型转换 0、、null、undefined都是false其他都是true deptList.value result.data; //拿到数据-数组 } }; const deptList ref([]); /script template h1部门管理/h1 div classcontainer el-button typeprimary 新增部门/el-button /div div classcontainer el-table :datadeptList border stylewidth: 100% el-table-column propid label序号 width100 aligncenter / el-table-column propname label部门名称 width260 aligncenter / el-table-column propupdateTime label最后操作时间 width300 aligncenter / el-table-column propaddress label操作 aligncenter template #defaultscope el-button typeprimary sizesmall el-iconEditPen //el-icon编辑/el-button el-button typedanger sizesmall el-iconDeleteFilled //el-icon删除/el-button /template /el-table-column /el-table /div /template style scoped .container { margin: 10px 0px; } /style3程序优化1为解决上述问题我们在前端项目开发时通常会定义一个请求处理的工具类-request.js与服务端进行异步交互的逻辑通常会封装到一个单独的api中如dept.js。在src目录下新建utils/request.js创建请求处理工具类并导出请求工具src/api/depts目录下导入工具并导出查询操作使用工具的查询操作查询部门4程序优化2utils/request.js中指定url请求路径的前缀vite.config.js中配置前端请求服务器信息配置代理服务器交给后端8080端口的tomcat处理并把请求路径的/api替换为空串这样就做到了前端访问后端2、新增部门api/dept.js中//新增 export const addApi (dept) request.post(/depts, dept);src/views/dept/index.vue中提示 新增部门和编辑部门可以共用一个dialog对话框。在ElementPlus提供的form表单组件中就提供了对应的表单校验的功能。具体步骤如下:定义表单校验规则通过rules属性与表单绑定通过prop属性绑定对应的表单项。通过ref属性注册表单的引用表单提交时校验表单校验通过则允许提交表单。//Dialog对话框 const dialogFormVisible ref(false);//控制弹窗显示 / 隐藏的响应式变量 const formTitle ref();//弹窗的标题文字 const dept ref({name: });//保存弹窗表单里部门的表单数据对象。//新增部门 const addDept () { dialogFormVisible.value true; formTitle.value 新增部门; dept.value {name: };//再次打开清空 //重置表单的校验规则-提示信息 if (deptFormRef.value){ deptFormRef.value.resetFields(); } }3、修改部门对于修改操作通常会分为两步进行①查询回显、②保存修改。//根据ID查询 export const queryByIdApi (id) request.get(/depts/${id});//路径参数传输使用模板字符串 //修改 export const updateApi (dept) request.put(/depts, dept);交互逻辑点击编辑按钮根据ID进行查询弹出对话框完成页面回显展示。查询回显//编辑 const edit async (id) { formTitle.value 修改部门; //重置表单的校验规则-提示信息 if (deptFormRef.value){ deptFormRef.value.resetFields(); } const result await queryByIdApi(id); if(result.code){ dialogFormVisible.value true; dept.value result.data; } }点击确定按钮保存修改后的数据完成数据更新操作。保存修改let result ; if(dept.value.id){ //修改 result await updateApi(dept.value); }else{ //新增 result await addApi(dept.value); }4、删除部门点击删除按钮需要删除当前这条数据删除完成之后刷新页面展示出最新的数据。 由于删除是一个比较危险的操作为避免误操作通常会在点击删除之后弹出确认框进行确认。四、员工管理-列表查询1、页面布局搜索栏2、页面布局搜索栏-watch侦听如果表单封装的数据较多建议绑定到一个对象中作用侦听一个或多个响应式数据源并在数据源变化时调用传入的回调函数。用法1、导入watch函数2、执行watch函数传入要侦听的响应式数据源ref对象和回调函数侦听对象// 1. 侦听一个响应式数据 const a ref(); watch(a, (newVal, oldVal) { console.log(变化后的值: ${newVal}, 变化前的值: ${oldVal}); }) // 2. 侦听一个对象(侦听对象的全部属性) const user ref({name: , age: 10}); watch(user, (newVal, oldVal) { console.log(newVal); }, {deep: true}) //深度侦听 // 3. 侦听对象中的某一个属性 const user2 ref({name: , age: 10}); watch(() user2.value.age, (newVal, oldVal) { console.log(变化后的值: ${newVal}, 变化前的值: ${oldVal}); })小结1、watch侦听函数的作用?侦听一个或多个响应式数据源并在数据源变化时调用所给的回调函数2、watch函数调用时传入的参数?参数一侦听的源可以是一个ref对象一个函数等。参数二侦听的源发生变化时触发的回调函数参数三可选是一个对象(deep、immediate)3、能否侦听对象的一个属性或全部属性可以侦听一个属性第一个参数传递一个函数user.value.name侦听全部属性第三个参数传递一个对象指定deep深度侦听3、页面布局表格4、页面布局分页条5、页面交互五、员工管理-新增员工1、页面布局引入2、页面布局展示优化3、页面布局Upload组件4、页面交互工作经历5、页面交互工作经历-watch监听6、页面交互保存员工7、页面交互表单校验六、员工管理-修改员工1、查询回显2、修改数据七、员工管理-删除员工1、删除单个2、批量删除八、登录退出1、登录功能实现2、携带令牌访问服务端3、携带令牌访问服务端Upload组件处理九、登录-响应401跳转登录页面十、退出1、展示当前登录员工2、功能实现十一、Tlias案例-打包部署1、生成打包文件2、安装Nginx代理服务器介绍Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件IMAP/POP3代理服务器。其特点是占有内存少并发能力强在各大型互联网公司都有非常广泛的使用。官网nginx3、部署Nginx服务器将上面的打包文件放到html目录下双击可执行文件启动4、访问前后端访问 http://localhost:80并运行后端注意Nginx默认占用80端口号如果80端口号被占用可以在Nginx.conf中修改端口号。使用新的nginx.conf文件进行反向代理nginx目录下cmd重新加载nginx的配置文件停止nginx服务器十二、关键字总结1、导入组件1vite.config.js 配置文件// 转成电脑真实磁盘路径字符串;拼装文件路径地址;* import { fileURLToPath, URL } from node:url //写代码时有代码提示、语法校验* import { defineConfig } from vite //让 vite 能识别.vue单文件组件* import vue from vitejs/plugin-vue2main.js 主入口//Vue3 的创建应用实例的函数。 import { createApp } from vue //创建 Pinia 实例用于全局共享状态数据登录用户信息、全局变量等。 import { createPinia } from pinia //导入根组件 import App from ./App.vue import router from ./router //导入 Element‑Plus UI 组件库vue3 版本提供 el‑button、el‑table、el‑dialog、el‑form 等全套组件。 import ElementPlus from element-plus //导入 Element‑Plus 的全部 css 样式文件。 //⚠️必须导入不导入所有 element 组件没有样式页面样式错乱。 import element-plus/dist/index.css // 把组件默认英文改成中文 import zhCn from element-plus/es/locale/lang/zh-cn //把图标库全部图标一次性导入 import * as ElementPlusIconsVue from element-plus/icons-vue // 导入项目全局自定义 css import ./assets/main.css3request.js 携带token//axios 网络请求库用来发 http 请求。 import axios from axios //消息提示组件 import { ElMessage } from element-plus //vue‑router 路由对象可以做页面跳转比如没登录跳转到登录页。 import router from ../router4conter.js 全局仓库容器//Vue3 响应式 API定义基础类型响应式数据数字、字符串、布尔。 //依赖别的响应式数据自动算出新值依赖的数据变了它自动更新不能直接手动赋值。 import { ref, computed } from vue //pinia 提供的函数用来创建全局仓库 store。 import { defineStore } from pinia5api包 发送请求交接后端//导入根组件 //自带请求拦截器自动带 token、响应拦截器。所有接口都使用这个 request 发请求不用原生 axios。 import request from /utils/request6views包 主布局页面//定义响应式数据。简单类型字符串、数字、布尔或者对象数组用 ref 包裹页面才会数据驱动数据变页面自动更新。 //生命周期钩子函数。组件渲染完成页面挂载完毕自动执行一般在这里加载页面初始数据比如一进来就查询部门列表。 import { ref, onMounted } from vue // ElMessage轻提示消息成功 / 失败提示 // ElMessageBox确认弹窗删除前弹框确认 import { ElMessage, ElMessageBox } from element-plus // 前面讲的部门接口文件导入已经封装好的后端请求函数。 import { queryAllApi, addDeptApi, queryInfoApi, updateDeptApi, deleteDeptApi } from /api/dept
阅读完成 · 觉得有帮助?