在线教育项目第五天

讲师管理模块前端开发

使用vue-admin-template框架,其基于vue和element-ui

文章目录

1、登录功能改造

首先将登录的url接口改为本地,因为easymock服务器很容易挂掉。后面会加上一个权限框架spring security
将登录请求的地址改为本地地址
原先的地址是由下面两个文件中的设置拼接的,基础地址+接口地址
config/dev.env.js BASE_API改为http://localhost:8001
    之前在service/service/edu中的application.properties文件中设置了server.port=8001
    注意不能使用https,这个需要相关部门的认证
src/api/login.js
    这里登录请求调用的底层代码在src/store/modules/user.js,调用了login登录方法和info登录后获取用户信息方法,
    所以我们要创建这两个方法来实现登录
        login 返回token
        info 返回roles name avatar
开发接口
EduLoginController
    加上RestController接口 交给spring管理,能够返回数据
    加上RequestMapping接口,参数是请求地址
    创建login方法
        加上PostMapping接口
        根据前端user.js中的login方法得知需要将token返回给前端
    创建info方法
        加上GetMapping接口
        根据前端user.js中的info方法得知需要将roles name avatar返回给前端
修改前端src/api/login.js中的请求url
是controller的请求地址与方法的请求地址的拼接
login方法改为eduservice/user/login
getInfo方法改为eduservice/user/info
接口中方法的提交方式和这里的提交方式一致
注意前端修改配置文件需要重启服务器
ctrl+c
npm run dev
出现Network Error说明代码有问题
No 'Access-Control-Allow-Origin' 访问不被允许 跨域问题
跨域:通过一个地址访问另一个地址,过程中下列三项有一项不一样就会产生跨域
        访问协议 IP 端口号
        当前前端使用9528端口访问前端项目,调用端口是8001的后端接口
解决:法1 后端接口controller上加上注解@CrossOrigin 常用 每个controller都加上
     法2 使用网关 后面spring cloud会用到
细节
每个请求都会有2次,一次是OPTIONS,一次是对应的请求方式GET/POST...
OPTIONS是预请求,测试接口是否可以连接成功,成功后再真正发送请求

2、前端框架使用过程

添加路由
src/router/index.js 复制修改示例
点击路由,要显示对应内容 import引入页面 @/在框架中就是./
在api中创建文件
引入request文件,其对axios进行了封装
定义请求接口的方法
在views中写vue页面 .vue
script中引入api中的文件
编写data定义变量和初始值 created调用methods中的方法 methods定义方法
页面中的template标签使用element-ui显示数据

3、讲师列表

添加路由
{
  path: '/teacher',
  component: Layout,//布局
  redirect: '/teacher/table',//访问teacher默认访问table
  name: '讲师管理',
  meta: { title: '讲师管理', icon: 'example' },
  children: [
    {
      path: 'table',
      name: '讲师列表',
      component: () => import('@/views/edu/teacher/list'),
      meta: { title: '讲师列表', icon: 'table' }
    },
    {
      path: 'add',
      name: '添加讲师',
      component: () => import('@/views/edu/teacher/save'),
      meta: { title: '添加讲师', icon: 'tree' }
    }
  ]
}
路径写错保存时控制台会报错 This dependency was not found
创建路由对应的页面
在views中创建edu/teacher文件夹
创建list.vue和add.vue
在api文件夹中定义请求接口的文件teacher.js 定义要访问的地址
//讲师列表 条件查询带分页
//当前页码 每页记录数 条件组合
getList(current, size, condition) {
    return request({
    //url: '/eduservice/teacher/pageTeacherCondition/' + current +'/' + size,
      url:`/eduservice/teacher/pageTeacherCondition/${current}/${size}`,
      method: 'post',
      data: condition //后端使用RequestBody获取json数据,需要在这里加上data表示将condition对象转为json数据传递到接口中
    })
}
在页面中的methods里定义方法,调用上面的方法,获取数据
getList() {
    teacher.getList(this.current, this.size, this.condition)
        .then(response => {
            //response 接口返回的数据
            console.log(response)
            this.list = response.data.items
            this.total = response.data.total
        })
        .catch(error => {
            console.log(error)
        })
}
在页面中显示数据
使用element-ui的表格组件
将:data="list"中的list改为自己的f12中返回的数据中data的下一级对象名,这里就是items
    {success: true, code: 20000, message: "成功"...}
        code:20000
        data:
            items:
        message:
        success:
将el-table-column标签中的prop改为返回的数据中的属性名,label改为要显示的列名
实现分页功能
使用element-ui的分页组件
    <el-pagination
        background
        layout="total, prev, pager, next, jumper"
        :current-page="current"
        :page-size="size"
        :total="total"
        @current-change="getList"><!-- 事件绑定,每次页面切换都调用getList 会自动将点击的页码作为参数传入-->
    </el-pagination>
    注意调用函数时()不能加上,否则点击页码不能跳转
修改getList方法,传入当前点击的页码
    getList(current = 1) {
        this.current = current;
        teacher.getList(this.current, this.size, this.condition)
实现条件查询功能
使用element-ui的表单组件
    将el-form标签中的:model="condition"改为自己在data中定义的条件查询组合对象,这里就是condition
    将el-form-item的v-model="condition.name"改为条件查询组合对象中的属性名,
        可以不在data中的condition中对属性进行定义,js在数据绑定后会自己加进去,定义也没错
    将el-button标签中的@click="getList()"改为自己定义的条件查询函数
        注意()要加上,否则会出现跨域问题
清空按钮
    resetData() {
        //清空输入的数据 查询表单中的数据和condition对象进行了双向绑定
        this.condition = {}
        //查询所有记录
        this.getList()
    }
    <el-button type="default" @click="resetData()">清空</el-button>
细节
方法的.catch()可以不写,已经在request中进行了封装,会对错误进行输出

4、讲师添加

点击添加讲师路由显示讲师添加页面
使用element-ui的表单组件创建讲师添加页面
data方法中返回teacher对象
    data() {
      return {
          teacher: {
              name: '',
              sort: 0,
              level: 1,
              career: '',
              intro: '',
              avatar: ''
          },
          addBtnDisabled: false //点击添加按钮后,按钮禁用,防止多次提交
      }
    }
给每个表单项使用v-model双向绑定上data中teacher对象的属性
注意头衔level的表单项要在value前加上: 这样页面上显示的就是默认值1对应的高级讲师
在methods中创建add方法,调用teacher中的添加方法
add() {
    teacher.add(this.teacher)
        .then(response => {
            this.$message({
                type: 'success',
                message: '添加成功!'
            });
            //回到列表页面查询所有 路由跳转
            this.$router.push({path: '/teacher/list'})
        })
}
在teacher.js中创建添加方法
add(teacher) {
    return request({
      url:`/eduservice/addTeacher`,
      method: 'post'
    })
}
添加成功后跳转到列表页面,为了使刚添加的数据在第一行,在EduTeacherController中的pageTeacherCondition方法中加上根据创建时间排序的代码
wrapper.orderByDesc("gmt_create");
注意
数据库中name字段是unique,添加相同姓名的讲师会报错

5、讲师删除

添加删除按钮,绑定删除方法,通过表格域scope得到每一行中的id scope.row.id
<el-button size="mini" type="danger" @click="removeDataById(scope.row.id)">删除</el-button>
Vue中创建删除方法传入讲师id,调用teacher.js中的删除方法
使用element-ui的弹框组件
removeDataById(id) {
    this.$confirm('此操作将永久删除该讲师记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        teacher.removeDataById(id)
            .then(response => {
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
                //回到列表页面查询所有
                this.getList()
            })
    }).catch(() => {
        this.$message({
            type: 'info',
            message: '已取消删除'
        });
    });
}
teacher.js中创建删除方法
removeDataById(id) {
    return request({
      url:`/eduservice/teacher/${id}`,
      method: 'delete'
    })
}

6、讲师修改

添加修改按钮,绑定修改方法,通过路由进行跳转
<router-link :to="'/teacher/update/' + scope.row.id">
    <el-button size="mini" type="primary">编辑</el-button>
</router-link>
点击修改按钮后,先根据id查询数据,跳转到一个表单中进行回显
添加一个修改表单的路由,其是隐藏路由,不在页面上进行显示
{
  path: 'update/:id',//:id是占位符
  name: '编辑讲师',
  component: () => import('@/views/edu/teacher/save'),
  hidden: true
}
和添加讲师使用同一个表单
数据回显
在teacher.js中定义方法findById
findById(id) {
  return request({
    url:`/eduservice/teacher/getTeacherById/${id}`,
    method: 'get'
  })
}
在save页面中的methods定义findById方法,调用teacher中的findById方法
findById(id) {
    teacher.findById(id)
        .then(response => {
            this.teacher = response.data.teacher
        })
}
根据路径中是否存在id来判断是添加讲师操作还是编辑讲师操作,因为二者使用了同一个页面
if(this.$route.params && this.$route.params.id) {
    //如果路径中存在id,则将id传入findById方法 这里的id要和index.js中的路由的path: 'update/:id'中的id一致
    const id = this.$route.params.id
    this.findById(id)
}
在teacher.js中创建修改讲师的方法update
update(teacher) {
  return request({
    url:`/eduservice/teacher/updateTeacher`,
    method: 'post',
    data: teacher
  })
}
在save页面中的methods里创建update方法,调用teacher中的update方法
update(teacher) {
    teacher.update(this.teacher)
        .then(response => {
            this.$message({
                type: 'success',
                message: '修改成功!'
            });
            //回到列表页面查询所有 路由跳转
            this.$router.push({path: '/teacher/list'})
        })
}
在save页面中的methods里的save方法中根据teacher对象中是否包含id值来判断调用添加方法还是修改方法
save() {
    if(this.teacher.id) {
        this.update()
    } else{
        this.add()
    }
}

7、bug解决

点击编辑讲师,数据会回显,再点击添加讲师,表单中的数据不会清空
解决:created中如果路径不含id,清空teacher对象
    created() {
        if(this.$route.params && this.$route.params.id) {
            //如果路径中存在id,则将id传入findById方法 这里的id要和index.js中的路由的path: 'update/:id'中的id一致
            const id = this.$route.params.id
            this.findById(id)
        } else {
            //路径中没有id,表示是添加操作,将teacher对象清空
            this.teacher = {}
        }
    }
    上面的代码失效的原因是添加和编辑属于两次路由跳转跳到了同一个页面,页面中的created方法只会执行一次
    使用vue监听来解决
        将上面created中的代码封装为一个init方法,加入到methods中
            init() {
                if(this.$route.params && this.$route.params.id) {
                    //如果路径中存在id,则将id传入findById方法 这里的id要和index.js中的路由的path: 'update/:id'中的id一致
                    const id = this.$route.params.id
                    this.findById(id)
                } else {
                    //路径中没有id,表示是添加操作,将teacher对象清空
                    this.teacher = {}
                }
            },
        在save页面中添加watch属性,每次路由变化时,调用init方法
            watch: {
                //监听
                //参数是路由变化的方式
                $route(to, from) {
                    this.init()
                }
            },
        created方法也调用init方法
            created() {
                this.init()
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值