文章目录
- 1 搭建前端项目环境
- 2 前端页面框架介绍
- 3 讲师管理前端开发
- 4 后台系统登录功能改造到本地
- 5 前端框架开发过程
- 6 讲师列表前端实现
- 7 讲师分页前端实现
- 8 讲师条件查询前端实现
- 9 讲师删除功能前端实现
- 10 讲师添加前端实现
- 11 讲师修改前端实现
- 12 前端路由切换问题解决
1 搭建前端项目环境
-
B2C模式
- 管理员——后台管理系统
- 后端接口
- 前端页面
- 用户——前台用户系统
- 管理员——后台管理系统
-
选取模板 环境搭建 vue-admin-template
- 使用模板:vue-admin-template-master
- webstorm打开项目
- 通过配置文件下载依赖
npm install
或解压文件中的node_modules并复制到项目中 - 启动项目:npm run dev
2 前端页面框架介绍
- 前端框架入口
- index.html
- main.js
- 前端页面环境使用框架(模板)
- vue-admin-template = vue + element-ui
- build目录
- 放项目构建的脚步文件
- config目录
- index.js 修改:
useEslint: false
- dev.env.js 修改访问后端接口地址
- index.js 修改:
- src目录
- api:定义调用方法
- assets:静态资源
- components:组件
- icons:图标
- router:路由
- utils:工具类
- views:具体页面
3 讲师管理前端开发
- 讲师列表(分页条件查询)
- 讲师添加
- 讲师删除
- 讲师修改
用vue-admin-template模板进行前端开发
首先把后台管理系统登录改造本地(临时),后面再把登录添加权限框架 spring security
4 后台系统登录功能改造到本地
-
更改系统登录默认地址
-
https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin/user/login =>http://localhost:8001/user/login
-
-
修改配置文件请求地址,在config/dev.env.js,修改:
BASE_API: '"http://localhost:8001"'
-
进行登录需要调用两个方法,所以要创建接口两个方法实现登录
- login:登录操作——返回token
- info:登录后获取用户信息——返回:roles、name、avatar
-
开发接口Controller
@RestController @RequestMapping("/eduservice/user") public class EduLoginController { // login @PostMapping("login") public R login() { return R.ok().data("token", "admin"); } // info @GetMapping("info") public R info() { return R.ok().data("roles", "[admin]").data("name", "admin").data("avatar", "https://profile.csdnimg.cn/9/0/4/1_mys_mys"); } }
-
修改api/login.js,改为本地接口路径
url: '/eduservice/user/login'
-
-
跨域问题:协议、IP地址、端口号有一个不一样
-
解决方式
-
后端接口controller中加注解
@CrossOrigin // 跨域访问 public class EduLoginController {}
-
使用网关解决
-
-
5 前端框架开发过程
-
添加路由 src/router/index.js
-
点击某个路由,显示路由对应的页面,并在views中创建vue
component: () => import('@/views/form/index'),
-
在api文件夹创建js文件,定义接口地址和参数
import request from '@/utils/request' export function getList(params) { return request({ url: '/table/list', method: 'get', params }) }
-
在创建的vue页面引入js文件,调用方法实现功能
import user from ... data: {}, created: {}, methods: {}
-
使用element-ui显示数据内容
6 讲师列表前端实现
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' }
}
]
},
2 创建路由对应的页面
views/edu/teacher/list.vue save.vue
<template>
<div class="app-container">
讲师列表
</div>
</template>
3 在api文件夹创建edu/teacher.js定义访问的接口地址
import request from '@/utils/request'
export default {
// 1 讲师列表
// current:当前页 limit:每页记录数 teacherQuery:条件对象
getTeacherListPage(current, limit, teacherQuery) {
return request({
url: `/eduservices/teacher/pageTeacherCondition/${current}/${limit}`,
method: 'post',
// teacherQuery条件对象,后端使用RequestBody获取数据
// data表示把对象转换成json进行传递到接口里
data: teacherQuery
})
}
}
4 在讲师列表页面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 => { // 请求成功
this.list = response.data.rows
this.total = response.data.total
console.log(this.list)
})
.catch(error => { // 请求失败
console.log(error)
})
}
}
}
</script>
5 把请求接口获取的数据在页面上显示
使用组件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"/>
</el-table>
</div>
</template>
7 讲师分页前端实现
1 讲师列表添加分页实现
<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"
/>
2 分页方法的修改,添加页码参数
getList(page = 1) {
this.page = page
......
}
8 讲师条件查询前端实现
1、使用element-ui组件实现,在列表上添加条件输入表单,使用v-model数据绑定
2、清空功能
-
清空表单输入条件数据
-
查询所有的数据
resetData() { // 表单输入项数据清空 this.teacherQuery = {} // 查询所有讲师数据 this.getList() }
<!--查询表单-->
<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>
9 讲师删除功能前端实现
1 在每条记录后面添加删除按钮
2 在按钮上绑定事件
@click=“removeDataById”
3 在绑定事件的方法传递删除讲师的id值
scope.row.id
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<router-link to="'/edu/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>
4 在api/edu/teacher.js定义删除接口的地址
deleteTeacherId(id) {
return request({
url: `/eduservice/teacher/${id}`,
method: 'delete'
})
}
5 在页面中调用方法,实现删除
removeDataById(id) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { // 点击确认,执行then方法
// 调用删除讲师方法
teacher.deleteTeacherId(id)
.then((response) => {
// 提示信息
this.$message({
type: 'success',
message: '删除成功!'
})
// 回到列表页面
this.getList()
})
})
}
10 讲师添加前端实现
1 点击添加讲师按钮,进入表单页面,输入讲师信息
<template>
<div class="app-container">
讲师表单
<el-form label-width="120px">
<el-form-item label="讲师名称">
<el-input v-model="teacher.name"/>
</el-form-item>
<el-form-item label="讲师排序" prop="sort">
<el-input-number v-model="teacher.sort" :min="0" controls-position="right" />
</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>
2 在表单页面点击保存,提交接口,添加数据库
-
api/edu/teacher.js中定义接口
addTeacher(teacher) { return request({ url: `/eduservice/teacher/addTeacher`, method: 'post', data: teacher }) }
-
在页面中调用
saveTeacher() {
teacherApi.addTeacher(this.teacher)
.then((response) => {
// 提示信息
this.$message({
type: 'success',
message: '保存成功!'
})
// 回到列表页面 路由跳转
this.$router.push({ path: '/teacher/table' })
})
}
11 讲师修改前端实现
1 在每条记录后面添加修改按钮
2 点击修改按钮,进入表单页面,进行数据的回显
根据讲师id查询数据显示
3 通过路由跳转进入数据回显页面,在路由index页面添加路由
{
path: 'edit/:id',
name: '编辑讲师',
component: () => import('@/views/edu/teacher/save'),
meta: { title: '编辑讲师', noCache: 'tree' },
hidden: true
}
<router-link to="'/teacher/edit' + scope.row.id">
<el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button>
</router-link>
4 在表单页面中实现数据回显
-
teacher.js中定义,根据id查询数据
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) } },
5 修改最终实现
-
在teacher.js定义修改接口
updateTeacher(teacher) { return request({ url: `/eduservice/teacher/updateTeacher`, method: 'post', data: teacher }) }
-
在页面调用修改方法
updateTeacher() {
teacherApi.updateTeacher(this.teacher)
.then((response) => {
// 提示信息
this.$message({
type: 'success',
message: '修改成功!'
})
// 回到列表页面 路由跳转
this.$router.push({ path: '/teacher/table' })
})
}
12 前端路由切换问题解决
-
第一次点击修改,进行数据回显,第二次再点击添加讲师,进入表单页面,但是表单页面回显的数据依然存在,正确效果应该是表单数据清空
-
解决方式:添加讲师时,清空表单
created() { // 判断路径是否有id值,有表示修改 if (this.$route.params && this.$route.params.id) { // 从路径获取id值 const id = this.$route.params.id // 根据id查询 this.getInfo(id) } else { // 没有,表示添加,在添加前需要清空表单 this.teacher = {} } },
-
但是并没有解决问题,为什么?
-
清空表单的方法放到created,第二次点击添加讲师时created里的方法并没有执行,created只在渲染之前执行
-
最终解决:使用vue监听
watch: { // 监听 $route(to, from) { // 路由变化的方式,路由发生变化,监听就会执行 this.init() } }, created() { this.init() }, methods: { init() { // 判断路径是否有id值,有表示修改 if (this.$route.params && this.$route.params.id) { // 从路径获取id值 const id = this.$route.params.id // 根虎id查询 this.getInfo(id) } else { // 没有,表示添加,在添加前需要清空表单 this.teacher = {} } },