上篇:
【在线教育】- 讲师模块功能实现
一、在线教育前端环境搭建
1.1、vue-element-admin 概述
1.2、vue-element-admin-master安装
# 解压压缩包
# 进入目录
cd vue-element-admin-master
# 安装依赖
npm install
# 启动。执行后,浏览器自动弹出并访问http://localhost:9527/
npm run dev
1.3、vue-element-template介绍(了解)
1.4、vue-element-template安装(了解)
# 解压压缩包
# 进入目录
cd vue-admin-template-master
# 安装依赖
npm install
# 启动。执行后,浏览器自动弹出并访问http://localhost:9527/
npm run dev
二、后台管理系统前端优化
2.1、修改项目信息(可选)
"name": "zx-study",
"version": "3.1.0",
"description": "在线教育后台管理系统",
"author": "XiaoXin <panfree23@gmail.com>",
2.2、修改端口号(可选)
- 在element-ui-admin 最新版本中,使用
vue-cli@3
构建项目,
-
vue-cli@3
构建的项目,核心配置文件 vue.config.js
- 修改端口号,有3种方式:
- 方式1:默认端口号
- 方式2:npm 配置端口号(注意=等左右没有空格)
npm run dev --port=8888
- 方式3:vue 运行环境中配置端口号
port=7777
2.3、项目的目录结构
.
├── build // 构建脚本
├── mock // 模拟数据服务
├── node_modules // 项目依赖模块 【*】
├── plop-templates // 模块生成工具
├── public // 静态资源目录,build之后,public目录下内容不合并,不压缩,直接拷贝到dist中
├── src //项目源代码 【**】
├── test // 测试程序目录
├── .env.development//开发环境下配置文件,VUE_APP_BASE_API
访问路径前缀【*】
├── .env.production //生产环境下配置文件,VUE_APP_BASE_API
访问路径前缀
├── package.json // 项目信息和依赖配置 【*】
└── vue.config.js // vue的核心配置文件 【**】
src
├── api // 接口目录 ,发送ajax代码 【**】
├── assets //静态资源目录,在build时,资源进行压缩、合并等操作。
├── components //公共组件目录,非公共组件在各自view下维护
├── directive //指令目录
├── filters // 过滤器目录
├── icons //svg icon
├── router // 路由表 【**】
├── store // 存储 vuex 【**】
├── styles // 各种样式
├── utils // 公共工具,非公共工具,在各自view下维护【*】
├── views // 各种layout 项目中所有的页面都放在此处【**】
├── vendor // 工具(excel、zip)
├── App.vue //项目顶层组件 【**】
├── main.js //项目入口文件 【*】
├── permission.js //认证入口【*】
└── settings.js 项目内容配置文件(项目标题)
2.4、运行项目
npm run dev
2.5、登录页面修改
- src/views/login/index.vue(登录组件),将
Login
修改成登录
2.6、页面零星修改
2.6.1、标题
2.6.2、国际化设置
- 打开 src/main.js,修改element ui 的语言为 zh-CN,使用中文语言环境,例如:日期时间组件
import enLang from 'element-ui/lib/locale/lang/zh-CN' //i18n
2.6.3、导航栏文字
<el-dropdown-menu slot="dropdown">
<router-link to="/profile/index">
<el-dropdown-item>Profile</el-dropdown-item>
</router-link>
<router-link to="/">
<el-dropdown-item>控制台</el-dropdown-item>
</router-link>
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
<el-dropdown-item>Github</el-dropdown-item>
</a>
<a target="_blank" href="https://panjiachen.gitee.io/vue-element-admin/">
<el-dropdown-item>在线演示</el-dropdown-item>
</a>
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
<el-dropdown-item>Docs帮助文档</el-dropdown-item>
</a>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
2.6.4、关机校验(必做)
- element-ui-admin 默认使用
eslint
代码检查工具
- 例如:注释后面没有添加空格
- 方式1:忽略所有文件的校验
- 方式2:关闭提示,在vue.config.js文件中,将 lintOnSave 修改成 false
// 校验默认开发状态开启
// lintOnSave: process.env.NODE_ENV === 'development',
lintOnSave: false,
三、前端路由实现分析
3.1、入口文件中调用路由
- src/main.js
3.2、定义路由模块
- src/router/index.js
- 步骤1:创建自定义路由文件
@/router/modules/teacher.js
- 步骤2:导入自定义路由文件
import teacherRouter from './modules/teacher' //自定义模块--老师模块
teacherRouter, //自定义模块--老师模块
3.3、编写路由模块文件
- 创建
@/router/modules/teacher.js
3.3.1、配置一个子路由
/** When your routing table is too long, you can split it into small modules **/
import Layout from '@/layout'
const teacherRouter = {
path: '/teacher', // 当前模块前缀路径,必须以/开头
component: Layout, // 采用布局组件显示当前模块【默认】
redirect: '/teacher/list', // “教师管理”默认显示路由
name: '教师管理', // 路由名称
meta: {
title: '教师管理', // 一级菜单名称,children.length==0 隐藏
icon: 'table' // 一级菜单图标,children.length==0 隐藏
},
children: [
{
path: 'list',
component: () => import('@/views/edu/teacher/list'),
name: '教师列表',
meta: { title: '教师列表' } //二级菜单名称
}
]
}
export default teacherRouter
3.3.2、配置多个子路由
/** When your routing table is too long, you can split it into small modules **/
import Layout from '@/layout'
const teacherRouter = {
path: '/teacher', // 当前模块前缀路径,必须以/开头
component: Layout, // 采用布局组件显示当前模块【默认】
redirect: '/teacher/list', // “教师管理”默认显示路由
name: '教师管理', // 路由名称
meta: {
title: '教师管理', // 一级菜单名称,children.length==0 隐藏
icon: 'table' // 一级菜单图标,children.length==0 隐藏
},
children: [
{
path: 'list',
component: () => import('@/views/edu/teacher/list'),
name: '教师列表',
meta: { title: '教师列表', icon: 'list' } //二级菜单名称
},
{
path: 'add',
component: () => import('@/views/edu/teacher/add'),
name: '添加教师',
meta: { title: '添加教师', icon: 'edit' } //二级菜单名称
}
]
}
export default teacherRouter
3.3.3、编写教师路由对应文件
- 创建列表页面 `@/views/edu/teacher/list.vue
<template>
<div>
教师管理
</div>
</template>
- 创建添加页面 `@/views/edu/teacher/list.vue
<template>
<div>
添加
</div>
</template>
四、后端接口分析
4.1、访问前缀
# just a flag
ENV = 'development'
# base api
# VUE_APP_BASE_API = '/dev-api'
VUE_APP_BASE_API = 'http://localhost:10010/'
4.2、axios工具类配置
4.2.1、查看工具类
// 导入axios
import axios from 'axios'
// 创建axios实例,并使用 VUE_APP_BASE_API 确定的访问前缀
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
// 请求处理(略)
service.interceptors.request.use(...)
// 响应处理(略)
service.interceptors.response.use(...)
// 返回处理后的axios
export default service
4.2.2、修改工具类
// 请求异常时,打印提示(路径等,数据等)
console.info(response.config, res)
4.2.3、禁用模拟数据
4.3、自定义后端接口
- 为了方面后期程序的维护,统一将所有axios访问路径,抽取到
@/api
下,且一个模块创建一个js文件。
4.3.1、修改用户登录文件
- 修改 `@/api/user.js
import axios from '@/utils/request'
export function login(user) {
//return axios.post('/user-service/user/login',user);
// 临时模拟
return axios.post('/teacher-service/user/login',user);
}
export function getInfo(token) {
//return axios.get('/user-service/user/info',{
return axios.get('/teacher-service/user/info',{
params: {token}
});
}
export function logout() {
return axios({
url: '/vue-element-admin/user/logout',
method: 'post'
})
}
- 在 teacher服务中,创建临时登录处理类
- JavaBean:User
@Data
public class User {
private String username;
private String password;
}
- 处理类:UserController,Element UI Admin
@RestController
@RequestMapping("/user")
public class UserController {
/**
* 用户登录
* @param user
* @return
*/
@PostMapping("/login")
public BaseResult login(@RequestBody User user) {
Map<String,Object> map = new HashMap<>();
if("admin".equals(user.getUsername())) {
map.put("token", "admin-token");
} else {
map.put("token", "editor-token");
}
return BaseResult.ok("登录成功",map);
}
@GetMapping("/info")
public BaseResult login(String token) {
Map<String,Object> map = new HashMap<>();
if("admin-token".equals(token)) {
map.put("roles", Arrays.asList("admin"));
map.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
map.put("name", "Super Admin");
} else {
map.put("roles", Arrays.asList("editor"));
map.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
map.put("name", "Normal Editor");
}
return BaseResult.ok("登录成功",map);
}
}
- 修改用户登录处理函数,打印错误信息,方便出错提示
4.3.2、教师接口文件
- 创建
@/api/edu/teacher.js
文件
// 导入axios工具类
import axios from '@/utils/request'
//编写具体功能,一个功能一个函数,并使用export导出
// 查询所有教师
export function findAll() {
return axios.get('/teacher-service/teacher')
}
// 添加教师
export function save(teacher) {
return axios.post('/teacher-service/teacher', teacher)
}
4.3.3、使用接口
<template>
<div>
教师管理
</div>
</template>
<script>
// 导入接口文件,并解构指定的方法
import { findAll } from '@/api/edu/teacher'
export default {
methods: {
async findAllTeacher() {
// 调用接口文件中接口到的方法
let { data } = await findAll()
}
},
mounted() {
// 页面加载成功,查询所有老师
this.findAllTeacher()
},
}
</script>
<style>
</style>
五、后台管理-讲师模块-前端实现
5.1、查询所有
5.1.1、需求
5.1.2、表格渲染
<template>
<div>
<el-table
v-loading="listLoading"
:data="teacherList"
border
fit
highlight-current-row
style="width: 100%;"
>
<el-table-column label="ID" prop="id" align="center" width="80">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name" align="center" width="80">
</el-table-column>
<el-table-column label="头衔" prop="id" align="center" width="120">
<template slot-scope="{row}">
<span>{{ row.level == 1 ? '高级讲师' : '首席讲师' }}</span>
</template>
</el-table-column>
<el-table-column label="资历" prop="intro" align="center" width="350">
</el-table-column>
<el-table-column label="添加时间" width="150px" align="center">
<template slot-scope="{row}">
{{row.gmtCreate}}
<span>{{ row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" width="80px" min-width="50px">
</el-table-column>
<el-table-column label="状态" width="100px" align="center">
<template slot-scope="{row}">
<span>{{ row.isDeleted == 1 ? '已删除' : '未删除' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="updateTeacher(row)">
修改
</el-button>
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="deleteTeacher(row,$index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
{{teacherList}}
</div>
</template>
<script>
// 导入接口文件,并解构指定的方法
import { findAll } from '@/api/teacher'
import { parseTime } from '@/utils'
export default {
data() {
return {
listLoading: true,
teacherList: []
}
},
methods: {
async findAllTeacher() {
this.listLoading = true
// 调用接口文件中接口到的方法
let { data } = await findAll()
this.teacherList = data
// 恢复状态
this.listLoading = false
},
updateTeacher() {
},
deleteTeacher() {
}
},
mounted() {
// 页面加载成功,查询所有老师
this.findAllTeacher()
},
}
</script>
<style>
</style>
5.2、分页列表
5.2.1、定义api
/* 条件查询
@param teacherPage 分页对象
@param teacherVo 条件对象
*/
export function condition(teacherPage,teacherVo) {
return axios.post(`/teacher-service/teacher/condition/${teacherPage.size}/${teacherPage.current}`, teacherVo)
}
5.2.2、分页实现
<template>
<div>
<el-table
v-loading="listLoading"
:data="teacherPage.records"
border
fit
highlight-current-row
style="width: 100%;"
>
<el-table-column label="ID" prop="id" align="center" width="80">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name" align="center" width="80">
</el-table-column>
<el-table-column label="头衔" prop="id" align="center" width="120">
<template slot-scope="{row}">
<span>{{ row.level == 1 ? '高级讲师' : '首席讲师' }}</span>
</template>
</el-table-column>
<el-table-column label="资历" prop="intro" align="center" width="350">
</el-table-column>
<el-table-column label="添加时间" width="150px" align="center">
<template slot-scope="{row}">
{{row.gmtCreate}}
<span>{{ row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" width="80px" min-width="50px">
</el-table-column>
<el-table-column label="状态" width="100px" align="center">
<template slot-scope="{row}">
<span>{{ row.isDeleted == 1 ? '已删除' : '未删除' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="updateTeacherPre(row)">
修改
</el-button>
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="deleteTeacher(row,$index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页条 -->
<pagination v-show="teacherPage.total>0" :total="teacherPage.total" :pageSizes="[1,2,3,5]" :page.sync="teacherPage.current" :limit.sync="teacherPage.size" @pagination="conditionTeacher" />
<!-- -->
</div>
</template>
<script>
// 导入接口文件,并解构指定的方法
import { findAll,condition } from '@/api/teacher'
import { parseTime } from '@/utils'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
export default {
components: { Pagination },
data() {
return {
listLoading: true,
teacherPage: { // 分页数据
current: 1,
size: 3,
total: 0
},
teacherVo: { // 查询条件
}
}
},
methods: {
/*
async findAllTeacher() {
this.listLoading = true
// 调用接口文件中接口到的方法
let { data } = await findAll()
this.teacherList = data
// 恢复状态
this.listLoading = false
},
*/
async conditionTeacher() {
this.listLoading = true
// 调用接口文件中接口到的方法
let { data } = await condition(this.teacherPage,this.teacherVo)
this.teacherPage = data
// 恢复状态
this.listLoading = false
},
updateTeacherPre() {
},
deleteTeacher() {
}
},
mounted() {
// 页面加载成功,查询所有老师
// this.findAllTeacher()
this.conditionTeacher()
},
}
</script>
<style>
</style>
5.2.3、条件
<!-- 分页 -->
<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="fetchData"
/>
5.2.4、条件表单
- 通过 value-format=“yyyy-MM-dd” 设置日期组件数据格式
<!-- 查询条件 -->
<div class="filter-container">
<el-form ref="conditionForm" :inline="true" :model="teacherVo" class="demo-form-inline">
<el-form-item >
<el-input v-model="teacherVo.name" placeholder="讲师名" style="width: 150px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-select v-model="teacherVo.level" placeholder="讲师头衔" clearable style="width: 150px" class="filter-item">
<el-option label="高级讲师" :value="1" />
<el-option label="首席讲师" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="12">
<el-date-picker type="date" placeholder="查询开始时间" v-model="teacherVo.beginDate" value-format="yyyy-MM-dd" style="width: 100%;"></el-date-picker>
</el-col>
<el-col :span="12">
<el-date-picker placeholder="查询结束时间" v-model="teacherVo.endDate" value-format="yyyy-MM-dd" style="width: 100%;"></el-date-picker>
</el-col>
</el-form-item>
<el-form-item >
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="conditionTeacher">
搜索
</el-button>
<el-button class="filter-item" style="margin-left: 10px;" @click="clearCondition">
清空
</el-button>
</el-form-item>
</el-form>
</div>
clearCondition() {
this.teacherVo = {}
}
5.2.5、BUG修复:element ui admin v-waves失效
// 修复波浪与@click冲突
// 参考:https://blog.csdn.net/hd243608836/article/details/110954416
const removeHandler = el[context].removeHandle
setTimeout(_ => {
el.removeEventListener('click', removeHandler, false)
})
el.addEventListener('click', handleClick(el, binding), false)
5.3、添加
5.3.1、定义Api
- src/api/edu/teacher.js (已有)
// 添加教师
export function save(teacher) {
return axios.post('/teacher-service/teacher', teacher)
}
5.3.2、显示添加页面
- 编写路由 (已有)
{
path: 'add',
component: () => import('@/views/edu/teacher/add'),
name: '添加教师',
meta: { title: '添加教师', icon: 'edit' } //二级菜单名称
}
- src/views/edu/teacher/add.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 type="primary" @click="saveTeacher">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
teacher: {
}
}
},
methods: {
saveTeacher() {
}
},
}
</script>
<style>
</style>
5.3.3、实现添加功能
- 导入 api,并修改 saveTeacher 发送ajax
<script>
// 导入ajax方法
import { save } from '@/api/teacher'
export default {
data() {
return {
teacher: {
}
}
},
methods: {
async saveTeacher() {
// ajax 查询,返回结果为BaseResult
let { message , data } = await save( this.teacher )
// 成功提示
this.$message.success( message )
// 关闭当前选项卡,【注意:必须放在跳转之前】
this.$store.dispatch('tagsView/delView', this.$route)
// 跳转到列表页面
this.$router.push('/teacher/list')
}
},
mounted() {
console.info(this.$refs)
},
}
</script>
5.3.4、扩展:关闭选项卡分析
// 关闭当前选项卡,【注意:必须放在跳转之前】
this.$store.dispatch('tagsView/delView', this.$route)
//操作vuex的标准写法
this.$store
//执行vuex的action的标准写法
this.$store.dispatch
// 执行模块“tagsView”中,名称为“delView”的action
tagsView/delView
// 参数为当前路由
this.$route
- vuex的位置
- 模块文件的位置
- action的位置
- 代码出处
5.4、修改&回显
5.4.1、定义回显Api
- src/api/teacher.js
// 查询详情
export function findById(id) {
return axios.get(`/teacher-service/teacher/${id}`)
}
5.4.2、显示修改弹出框
<!-- 修改弹出框 -->
<el-dialog title="修改讲师" :visible.sync="editDialogVisible">
<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>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" @click="updateTeacher">修改</el-button>
</div>
</el-dialog>
editDialogVisible: false, // 修改弹出框
teacher: { // 表单对象
}
5.4.3、调用回显Api
- 修改 src/views/edu/teacher/list.vue
- 从api解构 findById
// 导入接口文件,并解构指定的方法
import { findAll,condition, findById } from '@/api/teacher'
- 编写 findTeacherById方法,调用ajax方法
async findTeacherById(tid) {
// 查询结果 BaseResult
let { message, data } = await findById(tid)
// 保存查询结果
this.teacher = data
}
- 修改 updateTeacherPre 方法,显示弹出框,并回显表单
updateTeacherPre( teacher ) {
// 显示弹出框
this.editDialogVisible = true
// 查询详情
this.findTeacherById(teacher.id)
},
5.4.4、测试回显
5.4.5、定义修改Api
// 修改讲师
export function update( teacher ) {
return axios.put(`/teacher-service/teacher`, teacher)
}
5.4.6、调用修改Api
async updateTeacher() {
// 发送ajax
let { message } = await update( this.teacher )
// 提示
this.$message.success(message)
// 刷新列表
this.conditionTeacher()
// 关闭弹出框
this.editDialogVisible = false
}
5.5、删除
5.5.1、定义删除Api
// 通过id删除
export function deleteById(id) {
return axios.delete(`/teacher-service/teacher/${id}`)
}
5.5.2、调用删除Api
// 导入接口文件,并解构指定的方法
import { findAll,condition, findById, update, deleteById } from '@/api/teacher'
deleteTeacher( teacher ) {
this.$confirm('您确定要删除么?', '删除提示', {type: 'warning'})
.then(async () => {
// 确定
// 发送ajax
let { message } = await deleteById( teacher.id )
// 提示
this.$message.success(message)
// 刷新列表
this.conditionTeacher()
}).catch(() => {
// 取消
});
},
5.6、批量删除
5.6.1、后端实现
/**
* 批量删除
* @param ids
* @return
*/
@PostMapping("/deleteBatch")
public BaseResult deleteBatch(@RequestBody List<String> ids) {
boolean result = eduTeacherService.removeByIds(ids);
if(result) {
return BaseResult.ok("批量删除成功");
}
return BaseResult.error("批量删除失败");
}
5.6.2、定义批量删除Api
// 批量删除
export function deleteBatch( ids ) {
return axios.post(`/teacher-service/teacher/deleteBatch`, ids )
}
5.6.3、前端多选
- 添加多选框
<el-table-column
type="selection"
width="55">
</el-table-column>
- 添加多选事件
handleSelectionChange(val) {
this.multipleSelection = val;
}
multipleSelection: [] , //多选内容
5.6.4、调用批量删除Api
- 解构 deleteBatch
- 批量删除方法
deleteTeacherBatch() {
// 校验
if(this.multipleSelection.length <=0) {
this.$message.warning('请选择删除项')
return
}
// 确认
this.$confirm('您确定要删除所选讲师么?', '批量删除提示', {type: 'error'})
.then(async () => {
// 从选择内容中过滤所有的id
this.ids = this.multipleSelection.map(teacher=>teacher.id)
// 发送ajax
let { message } = await deleteBatch( this.ids )
// 提示
this.$message.success(message)
// 刷新列表
this.conditionTeacher()
}).catch(() => {
// 取消
});
}
5.6.5、批量按钮
<!-- 批量删除 -->
<el-button size="mini" type="danger" @click="deleteTeacherBatch">批量删除</el-button>
5.6.6、测试批量删除