一、概述
系统登录默认使用这个地址: https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin/user/login
把登录请求地址改造为本地:http://localhost:8001
修改配置文件中的请求地址
在config文件夹里有dev.env.js,修改:
BASE_API: '"http://localhost:8001"',
进行登录调用两个方法,login登录操作方法,info登录之后获取用户信息的方法
- login返回token值
- info返回roles、name、avatar(头像)
开发接口
// 该代码位于service_edu模块的controller包中 @RestController @RequestMapping("/eduservic/user") public class EduLoginController { // 登录的方法 @PostMapping("/login") public R loin(){ return R.ok().data("token","admin"); } // 获取信息的方法 @GetMapping("/info") public R info(){ return R.ok().data("roles","[admin]").data("name","admin").data("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"); } }
把前端文件src/login.js的url改为:
url: '/eduservic/user/login', // 包括login()方法和getInfo()方法,logout()方法暂时不改
重启前端项目:
npm run dev
最终测试出现了问题:跨域问题
通过一个地址访问另一个地址,这个过程中如果有三个地方任何一个不一样,就会产生跨域问题
- 访问协议:http https
- IP地址:192.168.1.1 172.11.11.11
- 端口号:9528 8001
跨越的解决方式
- 在后端接口controller上添加注解(最常用):@CrossOrigin
- 使用网关解决(后面会讲到)
测试
http://localhost:9529/
二、框架使用过程
添加路由(src/router/index.js),根据示例代码修改
点击某个路由,显示路由对应页面的内容
在api文件夹里创建js文件,定义接口地址和相关参数
在创建的vue页面中引入js文件,调用方法实现功能
- 引入 import user from ‘…’
最后使用element-ui显示数据内容
三、具体步骤
1.讲师列表(分页条件查询)
添加路由(在src/router/index.js下)
{ path: '/teacher', component: Layout, redirect: '/teacher/table', name: '讲师管理', meta: { title: '讲师管理', icon: 'example' }, children: [ { path: 'table', name: '讲师列表', component: () => import('@/views/edu/teacher/list'), meta: { title: '讲师列表', icon: 'table' } }, { path: 'save', name: '添加讲师', component: () => import('@/views/edu/teacher/save'), meta: { title: '添加讲师', icon: 'tree' } } ] },
创建路由对应的页面
// 在views/edu/teacher/list中: <template> <div class="app-container"> 讲师列表 </div> </template> // 在views/edu/teacher/save: <template> <div class="app-container"> 添加讲师 </div> </template>
在api文件夹中创建文件teacher.js,定义访问接口的地址
export default { /** * 1.讲师列表(条件查询分页) * @param {*} current 当前页 * @param {*} limit 每页显示几条记录 * @param {*} teacherQuery 条件对象 * @returns */ getTeacherList(current,limit,teacherQuery){ return request({ // url: '/table/list/' + current + "/" + "limit", url: `/eduservice/edu-teacher/pageTeacherCondition/${current}/${limit}`, method: 'post', // teacherQuery条件对象,后端使用@RequestBody获取数据 // data表示把对象转换成json传递到接口里 data:teacherQuery }) } }
在讲师列表页面(list.vue)调用定义的接口方法,得到接口的返回数据
<script> // 引入调用的teacher.js文件 import teacher from '@/api/edu/teacher' export default { // 核心代码 data(){ // 定义变量和初始值 return { list:null, // 查询之后接口返回的集合 page:1, // 当前页 limit:10, // 每页显示的记录数 total:0, // 总记录数 teacherQuery:{} // 条件封装对象 } }, created(){ // 页面渲染之前执行,调用methods定义的方法 // 调用 this.getList() }, methods:{ // 创建具体的方法,调用teacher.js定义的方法 // 讲师列表的方法 getList(){ teacher.getTeacherListPage(this.page,this.limit,this.teacherQuery) .then(response =>{// 请求成功 // response接口返回的数据 console.log(response) }) .catch(error => {console.log(error)}) // 请求失败 } } } </script>
把请求接口获取到的数据在页面中显示
使用组件 element-ui
<template> <div class="app-container"> 讲师列表 <!-- 表格 --> <el-table :data="list" border fit highlight-current-row> <el-table-column label="序号" width="70" align="center"> <template slot-scope="scope"> {{ (page - 1) * limit + scope.$index + 1 }} </template> </el-table-column> <el-table-column prop="name" label="名称" width="80" /> <el-table-column label="头衔" width="80"> <template slot-scope="scope"> {{ scope.row.level===1?'高级讲师':'首席讲师' }} </template> </el-table-column> <el-table-column prop="intro" label="资历" /> <el-table-column prop="gmtCreate" label="添加时间" width="160"/> <el-table-column prop="sort" label="排序" width="60" /> <el-table-column label="操作" width="200" align="center"> <template slot-scope="scope"> <router-link :to="'/teacher/edit/'+scope.row.id"> <el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button> </router-link> <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> </div> </template>
分页功能
<!--以下分页任选其一即可--> <!--分页--> <el-pagination background layout="prev, pager, next" @current-change="getList" style="text-align:center" :current-page="page" :page-size="limit" :total="total"> </el-pagination> <!-- 分页2 --> <el-pagination :current-page="page" :page-size="limit" :total="total" style="padding: 30px 0; text-align: center;" layout="total, prev, pager, next, jumper" @current-change="getList" /> <!--修改getList方法--> getList(page=1){...} this.page=page
讲师条件查询 + 分页
使用组件 element-ui
<!--查询表单--> <el-form :inline="true" class="demo-form-inline"> <el-form-item> <el-input v-model="teacherQuery.name" placeholder="讲师名"/> </el-form-item> <el-form-item> <el-select v-model="teacherQuery.level" clearable placeholder="讲师头衔"> <el-option :value="1" label="高级讲师"/> <el-option :value="2" label="首席讲师"/> </el-select> </el-form-item> <el-form-item label="添加时间"> <el-date-picker v-model="teacherQuery.begin" type="datetime" placeholder="选择开始时间" value-format="yyyy-MM-dd HH:mm:ss" default-time="00:00:00" /> </el-form-item> <el-form-item> <el-date-picker v-model="teacherQuery.end" type="datetime" placeholder="选择截止时间" value-format="yyyy-MM-dd HH:mm:ss" default-time="00:00:00" /> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="getList()">查询</el-button> <el-button type="default" @click="resetData()">清空</el-button> </el-form>
清空功能
清空表单输入条件
查询所有的数据
// 清空的方法 resetData(){ // 表单输入项数据清空 this.teacherQuery = {} // 查询所有讲师数据 this.getList() }
2.讲师添加
点击添加讲师的按钮,进入表单进行添加
<el-form label-width="120px"> <el-form-item label="讲师名称"> <el-input v-model="teacher.name"/> </el-form-item> <el-form-item label="讲师排序"> <el-input-number v-model="teacher.sort" controls-position="right" min="0"/> </el-form-item> <el-form-item label="讲师头衔"> <el-select v-model="teacher.level" clearable placeholder="请选择"> <el-option :value="1" label="高级讲师"/> <el-option :value="2" label="首席讲师"/> </el-select> </el-form-item> <el-form-item label="讲师资历"> <el-input v-model="teacher.career"/> </el-form-item> <el-form-item label="讲师简介"> <el-input v-model="teacher.intro" :rows="10" type="textarea"/> </el-form-item> <!-- 讲师头像:TODO --> <el-form-item> <el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存</el-button> </el-form-item> </el-form> </div> </template> <script> export default { data(){ return { teacher:{ name: '', sort: 0, level: 1, career: '', intro: '', avatar: '' }, saveBtnDisabled:false, // 保存按钮是否禁用 } }, created(){ }, methods:{ } } </script>
在表单页面点击保存,提交接口,添加到数据库中
/** * 添加讲师 * @param {*} teacher * @returns */ addTeacher(teacher){ return request({ url: `/eduservice/teacher/addTeacher`, method: 'post', data:teacher }) }
<script> import teacherApi from '@/api/edu/teacher' export default { data(){ return { teacher:{ name: '', sort: 0, level: 1, career: '', intro: '', avatar: '' }, saveBtnDisabled:false, // 保存按钮是否禁用 } }, created(){ }, methods:{ saveOrUpdate(){ this.saveTeacher() }, // 添加讲师的方法 saveTeacher(){ teacherApi.addTeacher(this.teacher) .then(response => { // 提示信息 this.$message({ type: 'success', message: '添加成功!' }); // 回到列表页面,路由跳转(重定向) this.$router.push({path:'/teacher/table'}) }) } } } </script>
添加排序效果
// 排序 wrapper.orderByDesc("gmt_create");
3.讲师删除
在每条记录后面添加删除按钮
在按钮上绑定删除事件
在绑定事件的方法传递删除讲师的id值
@click="removeDataById(scope.row.id)
在api文件夹的teacher.js定义删除接口的地址
/** * 根据id删除讲师 * @param {*} id 传入的讲师id * @returns */ deleteTeacherId(id){ return request({ url: `/eduservice/teacher/${id}`, method: 'delete' }) }
页面调用方法实现删除功能
弹窗
// 删除讲师的方法 removeDataById(id){ // 弹窗,确认删除 this.$confirm('此操作将永久删除讲师记录, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { // 调用删除的方法 teacher.deleteTeacherId(id) .then(response => { // 删除成功 // 提示信息 this.$message({ type: 'success', message: '删除成功!' }); // 回到列表页面 this.getList() }) }) }
4.讲师修改
点击修改按钮进入表单页面,进行数据回显。根据讲师id查询数据显示
跳转路由跳转进入数据回显页面,在路由index页面添加路由
{ // 添加和修改使用同一个页面,:id相当于一个占位符,等于 where id = ? path: 'edit/:id', name: 'EduTeacherEdit', component: () => import('@/views/edu/teacher/form'), meta: { title: '编辑讲师', noCache: true }, hidden:true }
在表单页面实现数据回显
在teacher.js定义根据id查询接口
/** * 根据id查询讲师 * @param {*} id * @returns */ getTeacherInfo(id){ return request({ url: `/eduservice/teacher/getTeacher/${id}`, method: 'get', }) }
在页面调用接口实现数据回显
// 根据讲师id查询的方法 getInfo(id){ teacherApi.getTeacherInfo(id) .then(response => { this.teacher = response.data.teacher }) },
调用根据id查询的方法
// 因为添加和修改都使用save页面,区分是添加还是修改,只有修改的时候查询数据回显 // 判断路径里是否有讲师的id值,如果有id值就做修改,如果没有就做添加 created(){ // 判断路径是否有id值 if(this.$route.params && this.$route.params.id){ // 从路径获取id值 const id = this.$route.params.id // 调用根据id查询的方法 this.getInfo(id) } },
最终修改实现
// 1.在api的teacher.js定义修改接口 /** * 修改讲师 * @param {*} teacher * @returns */ updateTeacherInfo(teacher){ return request({ url: `/eduservice/teacher/updateTeacher/`, method: 'post', data:teacher }) } // 2.在页面调用修改的方法 // 修改讲师的方法 updateTeacher(){ teacherApi.updateTeacherInfo(this.teacher) .then(response => { // 提示信息 this.$message({ type: 'success', message: '修改成功!' }); // 回到列表页面,路由跳转(重定向) this.$router.push({path:'/teacher/table'}) }) }, saveOrUpdate(){ // 判断是修改还是添加 // 根据teacher是否有id进行判断,有id是修改,没有id则是添加 if(!this.teacher.id){ // 添加 this.saveTeacher() }else{ // 修改 this.updateTeacher() } },
遇到问题
第一次点击修改,进行数据回显
第二次再点击添加讲师,进入表单页面,但是问题出现:表单页面还是显示修改回显的数据,正确的效果应该是表单数据清空
解决方法:做添加讲师的时候,表单数据清空就可以了
created(){ // 判断路径是否有id值,做修改操作 if(this.$route.params && this.$route.params.id){ // 从路径获取id值 const id = this.$route.params.id // 调用根据id查询的方法 this.getInfo(id) }else{ // 没有id值,做添加 // 清空表单 this.teacher = {} } },
上面的代码并没有解决问题,原因:多次路由跳转都到同一个页面,页面中的created()方法只会执行第一次,后面再进行跳转不会执行
最终的解决方案:使用vue监听
// 监听 watch:{ $route(to,form){ // 路由变化的方式,路由方式变化,方法执行 this.init() } }, created(){ this.init() }, init(){ // 判断路径是否有id值,做修改操作 if(this.$route.params && this.$route.params.id){ // 从路径获取id值 const id = this.$route.params.id // 调用根据id查询的方法 this.getInfo(id) }else{ // 没有id值,做添加 // 清空表单 this.teacher = {} } },