文章目录
一、环境搭建
1、使用GitHub下载vue-admin-template
仓库地址:git clone https://github.com/PanJiaChen/vue-admin-template.git
不会Git的看这里:https://blog.csdn.net/grd_java/article/details/106041657
2、使用HBuilderX的npm终端命令行安装依赖
3、使用命令npm run dev启动项目 进行测试
二、实现登陆功能
1、更改登陆请求地址
设置后台服务器请求端口
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8001`, //修改后台接口地址
changeOrigin: true,
pathRewrite: {
['^'+process.env.VUE_APP_BASE_API]: ''
}
}
},
设置环境变量
2、后端编写接口
package com.yzpnb.eduservice.controller;
import com.yzpnb.common_utils.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/eduservice/user")
@CrossOrigin//解决跨域问题
public class EduLoginController {
//login
@PostMapping("login")
public Result login()
{
/**
* token 登陆信息
*
*/
return Result.ok().data("token","admin");//之后我们都会使用框架,这里先写一个假数据admin之后再改
}
//info
@GetMapping("info")
public Result info()
{
/**
* name 名称
* avatar 头像
* 全部用假数据,头像是网上随便找的一张图片
*/
Map<String,Object> map=new HashMap<>();
map.put("name","admin");
map.put("avatar","http://i2.hdslb.com/bfs/face/d79637d472c90f45b2476871a3e63898240a47e3.jpg");
return Result.ok().data(map);//因为是单例模式,有多个值,需要用map
.data("avatar","http://i2.hdslb.com/bfs/face/d79637d472c90f45b2476871a3e63898240a47e3.jpg");
}
}
3、更改前端接口请求路径和后端对应
4、测试
三、编写讲师管理模块的前端页面
1、创建我们自己的路由页面
2、添加路由
/* 讲师列表*/
{
path: '/teacher',
component: Layout,
redirect: '/teacher/list',
name: 'teacher',
meta: { title: '讲师管理', icon: 'example' },
children: [
{
path: 'list',
name: 'List',
component: () => import('@/views/teacher/list'),
meta: { title: '讲师列表', icon: 'table' }
},
{
path: 'save',
name: 'Save',
component: () => import('@/views/teacher/save'),
meta: { title: '添加讲师', icon: 'tree' }
},
]
},
3、编写api接口,获取后端数据
根据后端接口编写前端接口
import request from '@/utils/request'//引入request.js,它封装了axios请求处理
export default{
/* 获取所有讲师列表
* current 当前页
* size 每页记录数
*/
getList(current,size){
return request({
url: `/eduservice/limitSelect/${current}/${size}`,//和后台接口地址对应
method: 'get',//请求方式对应
})
}
}
4、编写list页面(展示所有讲师)
<template>
<div class="app-container">
<!-- 表格 -->
<el-table :data="list" border style="width: 100%">
<el-table-column prop="id" label="序号" width="70">
<template slot-scope="scope">
{{(current-1)*size+scope.$index+1}}
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="70"></el-table-column>
<el-table-column label="头衔" width="100">
<template slot-scope="scope" width="100"><!-- scope表示当前整个表中的数据,row表示当前行的数据 -->
{{ scope.row.level === 1 ?'高级讲师':'首席讲师'}}
</template>
</el-table-column>
<el-table-column prop="intro" label="资历" width="500"></el-table-column>
<el-table-column prop="gmtCreate" label="注册时间" width="200"></el-table-column>
<el-table-column prop="sort" label="排序" width="70"></el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button type="primary"
size="mini"
@click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页-->
<el-pagination
@current-change="getList"
:current-page="current"
:page-size="size"
:total="total"
layout=" total,prev, pager, next, jumper"
style="padding:30px 0;text-align: center;"
>
</el-pagination>
</div>
</template>
<script>
import eduTeacher from '@/api/teacher/eduTeacher.js';//这里多次出现@符号,是因为将@符号封装成了src,也就是说@表示根路径src
export default{
name:'list',
data(){
return{
/* 初始化变量*/
current:1,//表示当前页
size:5, //每页记录数
total:0, //总记录数
list:null,//存储返回的数据,若想看的里面的数据,在页面输出即可,或者你看后端的json数据
search:"",//搜索内容
}
},
created() {
this.getList();
},
methods:{
//讲师列表查询
getList(current =1)
{
this.current=current;
eduTeacher.getList(this.current,this.size)
.then(response =>{
console.log("请求成功,不要试图在这里输出请求后响应的对象response,这是异步,输出只会是一个空对象,它会在响应之前就执行完毕");
this.list=response.data.limitEduTeacher.records;
this.total=response.data.limitEduTeacher.total;
})
.catch(error=>{
console.log("请求失败"+error);
})
}
}
}
</script>
<style>
</style>
四、对数据的增删改
1、删除讲师
api接口:
/* 根据id删除
*
*/
deleteById(id){
return request({
url:`/eduservice/deleteById/${id}`,
method:'delete',
})
}
list.vue
//根据id删除
deleteById(id){
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
eduTeacher.deleteById(id);
console.log("请求删除成功");
this.getList(this.current);//删除成功重新请求,刷新页面
this.$message({
type: 'success',
message: '删除成功!'
});
})
},
2、添加
save.vue
<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="讲师排序">
<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="请选择">
<!--
数据类型一定要和取出的json中的一致,否则没法回填
因此,这里value使用动态绑定的值,保证其数据类型是number
-->
<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>
import eduTeacher from '@/api/teacher/eduTeacher.js'
export default{
data(){
return{
teacher:{
name:'',
sort:0,
level:1,
career:'',
intro:''
},
saveBtnDisabled:false
}
},
created() {
this.teacher.name=this.$router.query.a;
},
methods:{
saveOrUpdate(){//修改和添加,为了可以让修改和添加用同一个页面
this.save();
},
save(){/* 添加方法 */
eduTeacher.save(this.teacher)
.then(response =>{
//提示信息
console.log("成功")
//回到列表显示
this.$router.push({name:'teacher'})
})
}
}
}
</script>
<style>
</style>
api
/* 添加数据*/
save(data){
return request({
url:`/eduservice/insertEduTeacher`,
method:'post',
data
})
}
3、修改
后端添加一个跟随id查询数据的接口
添加一个子路由
点击修改按钮时,执行相应方法,跳转到子路由
api接口添加查询和修改接口
判断现在的路由是用来修改还是用来添加的
五、前端增删改查代码
1、api接口
import request from '@/utils/request'//引入request.js,它封装了axios请求处理
export default{
/* 分页获取所有讲师列表
* current 当前页
* size 每页记录数
*/
getList(current,size){
return request({
url: `/eduservice/limitSelect/${current}/${size}`,//和后台接口地址对应
method: 'get',//请求方式对应
})
},
/* 根据id删除
*
*/
deleteById(id){
return request({
url:`/eduservice/deleteById/${id}`,
method:'delete',
})
},
/* 添加数据*/
save(data){
return request({
url:`/eduservice/insertEduTeacher`,
method:'post',
data
})
},
/* 根据id查询数据*/
selectById(id){
return request({
url:`/eduservice/selectById/${id}`,
method:'get',
})
},
/* 修改数据*/
updateById(data){
return request({
url:`/eduservice/updateEduTeacher`,
method:'put',
data
})
}
}
2、list.vue
<template>
<div class="app-container">
<!-- 表格 -->
<el-table :data="list" border style="width: 100%">
<el-table-column prop="id" label="序号" width="70">
<template slot-scope="scope">
{{(current-1)*size+scope.$index+1}}
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="70"></el-table-column>
<el-table-column label="头衔" width="100">
<template slot-scope="scope" width="100"><!-- scope表示当前整个表中的数据,row表示当前行的数据 -->
{{ scope.row.level === 1 ?'高级讲师':'首席讲师'}}
</template>
</el-table-column>
<el-table-column prop="intro" label="资历" width="500"></el-table-column>
<el-table-column prop="gmtCreate" label="注册时间" width="200"></el-table-column>
<el-table-column prop="sort" label="排序" width="70"></el-table-column>
<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
size="mini"
placeholder="输入关键字搜索"/>
</template>
<template slot-scope="scope">
<el-button type="primary"
size="mini"
@click="updateById(scope.row.id)">Edit</el-button>
<el-button
size="mini"
type="danger"
@click="deleteById(scope.row.id)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页-->
<el-pagination
@current-change="getList"
:current-page="current"
:page-size="size"
:total="total"
layout=" total,prev, pager, next, jumper"
style="padding:30px 0;text-align: center;"
>
</el-pagination>
</div>
</template>
<script>
import eduTeacher from '@/api/teacher/eduTeacher.js';//这里多次出现@符号,是因为将@符号封装成了src,也就是说@表示根路径src
export default{
name:'list',
data(){
return{
/* 初始化变量*/
current:1,//表示当前页
size:5, //每页记录数
total:0, //总记录数
list:null,//存储返回的数据,若想看的里面的数据,在页面输出即可,或者你看后端的json数据
search:"",//搜索内容
}
},
created() {
this.getList();
},
methods:{
//讲师列表查询
getList(current =1)
{
this.current=current;
eduTeacher.getList(this.current,this.size)
.then(response =>{
console.log("请求成功,不要试图在这里输出请求后响应的对象response,这是异步,输出只会是一个空对象,它会在响应之前就执行完毕");
this.list=response.data.limitEduTeacher.records;
this.total=response.data.limitEduTeacher.total;
})
.catch(error=>{
console.log("请求失败"+error);
})
},
//根据id删除
deleteById(id){
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
eduTeacher.deleteById(id);
console.log("请求删除成功");
this.getList(this.current);//删除成功重新请求,刷新页面
this.$message({
type: 'success',
message: '删除成功!'
});
})
},
//修改数据
updateById(id){
this.$router.push({name:'Update',params:{id}})
}
}
}
</script>
<style>
</style>
3、save.vue
<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="讲师排序">
<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="请选择">
<!--
数据类型一定要和取出的json中的一致,否则没法回填
因此,这里value使用动态绑定的值,保证其数据类型是number
-->
<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>
import eduTeacher from '@/api/teacher/eduTeacher.js'
export default{
data(){
return{
teacher:{
},
saveBtnDisabled:false
}
},
created() {
if(this.$route.params && this.$route.params.id){
this.selectById(this.$route.params.id);//如果路由中有参数并且参数是id值,则调用selectById方法,查询数据
}
},
methods:{
/* 根据id获取数据*/
selectById(id){
eduTeacher.selectById(id)
.then(response =>{
this.teacher=response.data.eudTeacher;//将数据存储到teacher中
})
.catch(error=>{
})
},
/* 添加方法 */
save(){
eduTeacher.save(this.teacher)
.then(response =>{
//提示信息
console.log("成功")
//回到列表显示
this.$router.push({name:'teacher'})
})
},
/* 修改方法*/
updateById(){
eduTeacher.updateById(this.teacher)
.then(response=>{
//回到列表显示
this.$router.push({name:'teacher'})
})
.catch(error=>{
})
},
/* 修改和添加,为了可以让修改和添加用同一个页面 */
saveOrUpdate(){
if(this.teacher.id){/* 如果teacher对象中有id值,说明是我们请求后的数据,执行的应该是修改 */
this.updateById();
}
else{/* 如果没有,说明我们仅仅添加数据,执行的应该是添加 */
this.save();
}
},
}
}
</script>
<style>
</style>
4、路由
/* 讲师列表*/
{
path: '/teacher',
component: Layout,
redirect: '/teacher/list',
name: 'teacher',
meta: { title: '讲师管理', icon: 'example' },
children: [
{
path: 'list',
name: 'List',
component: () => import('@/views/teacher/list'),
meta: { title: '讲师列表', icon: 'table' }
},
{
path: 'save',
name: 'Save',
component: () => import('@/views/teacher/save'),
meta: { title: '添加讲师', icon: 'tree' }
},
{
path: 'update/:id',
name: 'Update',
component: () => import('@/views/teacher/save'),
meta: { title: '添加讲师', icon: 'tree' },
hidden:true
},
]
},