5 讲师管理模块前端开发


一、概述

首先,把后台管理系统的登录功能改造成本地(临时),后面会把登录添加到权限框架SpringSecurity
  1. 系统登录默认使用这个地址: https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin/user/login

  2. 把登录请求地址改造为本地:http://localhost:8001

  3. 修改配置文件中的请求地址

    • 在config文件夹里有dev.env.js,修改:

      BASE_API: '"http://localhost:8001"',
  4. 进行登录调用两个方法,login登录操作方法,info登录之后获取用户信息的方法

    • login返回token值
    • info返回roles、name、avatar(头像)
  5. 开发接口

    // 该代码位于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
  6. 跨越的解决方式

    • 在后端接口controller上添加注解(最常用):@CrossOrigin
    • 使用网关解决(后面会讲到)
  7. 测试

    http://localhost:9529/

二、框架使用过程

  1. 添加路由(src/router/index.js),根据示例代码修改

  2. 点击某个路由,显示路由对应页面的内容

  3. 在api文件夹里创建js文件,定义接口地址和相关参数

  4. 在创建的vue页面中引入js文件,调用方法实现功能

    • 引入 import user from ‘…’
  5. 最后使用element-ui显示数据内容

三、具体步骤

1.讲师列表(分页条件查询)

  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中:
    <template>
        <div class="app-container">
            讲师列表
        </div>
    </template>
    
    // 在views/edu/teacher/save:
    <template>
        <div class="app-container">
            添加讲师
        </div>
    </template>
  3. 在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
              })
        }
    }
  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 =>{// 请求成功
                        // response接口返回的数据
                        console.log(response)
                    })     
                    .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">
            <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>
  6. 分页功能

    <!--以下分页任选其一即可-->    
    <!--分页-->
        <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
  7. 讲师条件查询 + 分页

    使用组件 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>
  8. 清空功能

    • 清空表单输入条件

    • 查询所有的数据

      // 清空的方法
      resetData(){    
          // 表单输入项数据清空
          this.teacherQuery = {}
          // 查询所有讲师数据
          this.getList()
      }

2.讲师添加

  1. 点击添加讲师的按钮,进入表单进行添加

     <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>
  2. 在表单页面点击保存,提交接口,添加到数据库中

    /**
     * 添加讲师
     * @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>
  3. 添加排序效果

    // 排序
    wrapper.orderByDesc("gmt_create");

3.讲师删除

  1. 在每条记录后面添加删除按钮

  2. 在按钮上绑定删除事件

  3. 在绑定事件的方法传递删除讲师的id值

    @click="removeDataById(scope.row.id)
  4. 在api文件夹的teacher.js定义删除接口的地址

    /**
     * 根据id删除讲师
     * @param {*} id 传入的讲师id
     * @returns 
     */
    deleteTeacherId(id){
        return request({
            url: `/eduservice/teacher/${id}`,
            method: 'delete'
        })
    }
  5. 页面调用方法实现删除功能

    • 弹窗

      // 删除讲师的方法
      removeDataById(id){
          // 弹窗,确认删除
          this.$confirm('此操作将永久删除讲师记录, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
              }).then(() => { 
                  // 调用删除的方法
                  teacher.deleteTeacherId(id)
                      .then(response => {     // 删除成功
                       // 提示信息
                            this.$message({
                            type: 'success',
                            message: '删除成功!'
                        });
                        // 回到列表页面
                        this.getList()
                    })
                })
      }

4.讲师修改

  1. 点击修改按钮进入表单页面,进行数据回显。根据讲师id查询数据显示

  2. 跳转路由跳转进入数据回显页面,在路由index页面添加路由

    {
      // 添加和修改使用同一个页面,:id相当于一个占位符,等于  where id = ?
      path: 'edit/:id',
      name: 'EduTeacherEdit',
      component: () => import('@/views/edu/teacher/form'),
      meta: { title: '编辑讲师', noCache: true },
      hidden:true
    }
  3. 在表单页面实现数据回显

    • 在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)
             }   
          },
  4. 最终修改实现

    // 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()
                }
                
            },
  5. 遇到问题

    • 第一次点击修改,进行数据回显

    • 第二次再点击添加讲师,进入表单页面,但是问题出现:表单页面还是显示修改回显的数据,正确的效果应该是表单数据清空

    • 解决方法:做添加讲师的时候,表单数据清空就可以了

      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 = {}
         }   
        },

文章作者: Prannt
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Prannt !
评论
  目录