微服务项目实战技术点汇总:“尚硅谷的谷粒在线教育” 二、vue搭建后台管理系统前端页面,并配合后端实现登陆和讲师的增删改查

一、环境搭建

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
      },
    ]
  },

猜你喜欢

转载自blog.csdn.net/grd_java/article/details/106050978
今日推荐