src/router/index.js
配置讲师管理相关路由
创建文件 src/api/teacher.js
前端请求接口定义,只是定义接口,不是实际调用,实际调用在,.vue文件中
// @ 符号在build/webpack.base.conf.js 中配置 表示 'src' 路径
import request from '@/utils/request'
export default {
list() {
return request({
url: '/admin/edu/teacher/list',
method: 'get'
})
}
}
src/views/teacher/list.vue
调用api获得数据
<script>
import teacherApi from '@/api/teacher'
export default {
// 定义数据模型
data() {
return {
list: [] // 讲师列表
}
},
// 页面渲染成功后获取数据
created() {
this.fetchData()
},
// 定义方法
methods: {
fetchData() {
// 调用api
teacherApi.list().then(response => {
this.list = response.data.items
})
}
}
}
</script>
数据做了一个:data="list"绑定,之后数据自动渲染到页面
<!-- 表格 -->
<el-table :data="list" border stripe>
<el-table-column type="index" width="50"/>
<el-table-column prop="name" label="名称" width="80" />
<el-table-column label="头衔" width="90">
<template slot-scope="scope">
<el-tag v-if="scope.row.level === 1" type="success" size="mini">高级讲师</el-tag>
<el-tag v-if="scope.row.level === 2" size="mini">首席讲师</el-tag>
</template>
</el-table-column>
<el-table-column prop="intro" label="简介" />
<el-table-column prop="sort" label="排序" width="60" />
<el-table-column prop="joinDate" label="入驻时间" width="160" />
</el-table>
src/api/teacher.js
get请求用 params传参,是键值对的形式,拼接到字符串后面
pageList(page, limit, searchObj) {
return request({
url: `/admin/edu/teacher/list/${page}/${limit}`,
method: 'get',
params: searchObj
})
}
src/views/teacher/list.vue,完善data定义,之后将完整参数发送请求,最后回显数据
data() {// 定义数据
return {
list: null, // 数据列表
total: 0, // 总记录数
page: 1, // 页码
limit: 10, // 每页记录数
searchObj: {}// 查询条件
}
}
修改fetchData方法
fetchData() {
// 调用api
teacherApi.pageList(this.page, this.limit, this.searchObj).then(response => {
this.list = response.data.rows
this.total = response.data.total
})
}
在table组件下面添加分页组件
<!-- 分页组件 -->
<el-pagination
:current-page="page"
:total="total"
:page-size="limit"
:page-sizes="[5, 10, 20, 30, 40, 50, 100]"
style="padding: 30px 0; text-align: center;"
layout="total, sizes, prev, pager, next, jumper"
/>
当注册时间有回调参数时不必要自己传入,也就是绑定的方法@size-change会自动注入一个参数,比如当前页,之后绑定方法的名字changePageSize可以不用传参,只需到时候调用随便给个参数名字之后就可以获得参数值,changePageSize(size),得到参数.这就好比回调函数的then中的response=>也不是自己创建的,到时候框架会自动获得.如果传入带()就成了方法调用,而不是方法引用框架就不会为我们获得参数,只是引用其中的方法.你传的东西啥事儿都干不了!
@size-change="changePageSize"
定义事件脚本
// 每页记录数改变,size:回调参数,表示当前选中的“每页条数”
changePageSize(size) {
this.limit = size
this.fetchData()
}
为组件注册事件
@current-change="changeCurrentPage"
定义事件脚本
// 改变页码,page:回调参数,表示当前选中的“页码”
changeCurrentPage(page) {
this.page = page
this.fetchData()
},
这里是防止到了第二页显示还是 1 2 3 4 这样的序号,然后会变为5 6 7 8
<el-table-column
label="#"
width="50">
<template slot-scope="scope">
{{ (page - 1) * limit + scope.$index + 1 }}
</template>
</el-table-column>
在table组件上面添加查询表单
<!--查询表单-->
<el-form :inline="true">
<el-form-item>
<el-input v-model="searchObj.name" placeholder="讲师"/>
</el-form-item>
<el-form-item>
<el-select v-model="searchObj.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="searchObj.joinDateBegin"
placeholder="开始时间"
value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="-">
<el-date-picker
v-model="searchObj.joinDateEnd"
placeholder="结束时间"
value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="fetchData()">查询</el-button>
<el-button type="default" @click="resetData()">清空</el-button>
</el-form-item>
</el-form>
重置表单脚本
// 重置表单
resetData() {
this.searchObj = {}
this.fetchData()
}
src/api/teacher.js
removeById(id) {
return request({
url: `/admin/edu/teacher/remove/${id}`,
method: 'delete'
})
}
在table组件中添加删除列
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="danger" size="mini" icon="el-icon-delete" @click="removeById(scope.row.id)">删除</el-button>
</template>
</el-table-column>
// 根据id删除数据
removeById(id) {
this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
return teacherApi.removeById(id)
}).then((response) => {
this.fetchData()
this.$message.success(response.message)
}).catch(error => {
console.log('error', error)
// 当取消时会进入catch语句:error = 'cancel'
// 当后端服务抛出异常时:error = 'error'
if (error === 'cancel') {
this.$message.info('取消删除')
}
})
}
code!==20000的响应会被拦截,并转到 error=>{} 处理
if (res.code !== 20000) {
return Promise.reject('error')
}
code===20000时放行,前端页面接收到response.data的值,而不是response
if (res.code !== 20000) {
return Promise.reject('error')
} else {
return response.data
}
统一处理错误结果,显示错误消息
如果是get请求传递键值对的话是param进行传参,如果后台需要json数据的话用data进行传参
src/api/teacher.js
save(teacher) {
return request({
url: '/admin/edu/teacher/save',
method: 'post',
data: teacher
})
}
src/views/teacher/form.vue,完善data定义
<script>
export default {
data() {
return {
// 初始化讲师默认数据
teacher: {
sort: 0,
level: 1
},
saveBtnDisabled: false // 保存按钮是否禁用,防止表单重复提交
}
}
}
</script>
src/views/teacher/form.vue
<el-form label-width="120px">
<el-form-item label="讲师名称">
<el-input v-model="teacher.name" />
el-form-item>
<el-form-item label="入驻时间">
<el-date-picker v-model="teacher.joinDate" value-format="yyyy-MM-dd" />
el-form-item>
<el-form-item label="讲师排序">
<el-input-number v-model="teacher.sort" :min="0"/>
el-form-item>
<el-form-item label="讲师头衔">
<el-select v-model="teacher.level">
<el-option :value="1" label="高级讲师"/>
<el-option :value="2" label="首席讲师"/>
el-select>
el-form-item>
<el-form-item label="讲师简介">
<el-input v-model="teacher.intro"/>
el-form-item>
<el-form-item label="讲师资历">
<el-input v-model="teacher.career" :rows="10" type="textarea"/>
el-form-item>
<el-form-item>
<el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate()">保存el-button>
el-form-item>
el-form>
src/views/teacher/form.vue,引入teacher api模块:
import teacherApi from '@/api/teacher'
定义保存方法
methods: {
saveOrUpdate() {
// 禁用保存按钮
this.saveBtnDisabled = true
this.saveData()
},
// 新增讲师
saveData() {
// debugger
teacherApi.save(this.teacher).then(response => {
this.$message({
type: 'success',
message: response.message
})
this.$router.push({ path: '/teacher' })
})
}
}
src/api/teacher.js
getById(id) {
return request({
url: `/admin/edu/teacher/get/${id}`,
method: 'get'
})
}
src/views/teacher/form.vue,methods中定义回显方法
// 根据id查询记录
fetchDataById(id) {
teacherApi.getById(id).then(response => {
this.teacher = response.data.item
})
}
页面渲染成功后获取数据
因为已在路由中定义如下内容:path: ‘edit/:id’,因此可以使用 this.$route.params.id 获取路由中的id
//页面渲染成功
created() {
if (this.$route.params.id) {
this.fetchDataById(this.$route.params.id)
}
}
src/views/teacher/list.vue,表格“操作”列中增加“修改”按钮
修改
src/api/teacher.js
updateById(teacher) {
return request({
url: '/admin/edu/teacher/update',
method: 'put',
data: teacher
})
}
src/views/teacher/form.vue,methods中定义updateData
// 根据id更新记录
updateData() {
// teacher数据的获取
teacherApi.updateById(this.teacher).then(response => {
this.$message({
type: 'success',
message: response.message
})
this.$router.push({ path: '/teacher' })
})
},
完善saveOrUpdate方法
saveOrUpdate() {
// 禁用保存按钮
this.saveBtnDisabled = true
if (!this.teacher.id) {
this.saveData()
} else {
this.updateData()
}
}
**问题:**vue-router导航切换 时,如果两个路由都渲染同个组件,
组件的生命周期方法(created或者mounted)不会再被调用, 组件会被重用,显示上一个路由渲染出来的自建
**解决方案:**可以简单的在 router-view上加上一个唯一的key,来保证路由切换时都会重新触发生命周期方法,确保组件被重新初始化。
修改 src/views/layout/components/AppMain.vue 文件如下:
computed: {
key() {
return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date()
}
}
解决:组件重用问题 每使用一次数学都会重新计算,而方法会从本地上次计算好的重新取出来.
创建 08-计算属性.html
new Vue({
el: '#app',
data: {
message: 'hello'
}
})
模板表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会难以维护。
原始值: {{ message }}
反转消息: {{ message.split('').reverse().join('') }}
所以,对于任何复杂逻辑,你都应当使用计算属性
computed: {
reversedMessage () {
console.log('计算属性执行')
return this.message.split('').reverse().join('')
}
}
反转消息: {{ reversedMessage }}
methods:{
reversed () {
console.log('方法执行')
return this.message.split('').reverse().join('')
}
}
反转消息: {{ reversed() }}
计算属性缓存 vs 方法
(https://cn.vuejs.org/v2/guide/computed.html#计算属性缓存-vs-方法)
看起来计算属性和方法能完成相同的功能,那么他们有什么区别呢?
反转消息: {{ reversedMessage }}
反转消息: {{ reversedMessage }}
反转消息: {{ reversed() }}
反转消息: {{ reversed() }}
组件(Component)是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用界面都可以抽象为一个组件树:
main.js 中引入了App.vue和 router/index.js,根据路由配置,App.vue中会显示相应的页面内容
src/main.js
src/App.vue
src/router/index.js
src/router/index.js
src/views/layout/Layout.vue
src/views/layout/components/AppMain.vue