在线教育-谷粒学院学习笔记(三)

  • Post author:
  • Post category:其他




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 修改访问后端接口地址
  • 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 = {}
        }
      },
    



版权声明:本文为mys_mys原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。