在这一部分主要完成以下几件事情
- 完成反馈面板的铺设和使用
- 完成axios请求和响应拦截器
-
- 完成频道管理
1 反馈面板的铺设和使用
主要完成以下工作
根据设计图完成以下操作
- 铺设下面的一级面板
- 铺设二级面板
- 返回一级面板
4.不感兴趣
5.举报文章
实现思路
1.铺设下面的一级面板
通过组件
通过响应拦截器来拦截
在axios当中有两个拦截器,一个是响应拦截器.一个是请求拦截器。
请求拦截器,当真正发起请求之前
响应拦截器,当请求发送出去,响应回来的数据
基于此在两个拦截器上分别添加方法
在相应拦截器上捕获错误,如果状态码为401就跳转到登陆页面
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 当状态码为2xx/3xx开头的进这里
// 对响应数据做点什么
return response
}, async function (error) { // 响应状态码4xx/5xx进这里
// 对响应错误做点什么
console.log(error.response.status);
if (error.response.status === 401) { // 身份过期
// token续签方式1: 去登录页重新登录, token无用, 清掉-确保路由守卫if进不去
// 不能使用this.$router (因为this不是vue组件对象无法调用$router)
Toast('请重新登录');
router.replace('/login')
// router.replace(`/login?path=${router.currentRoute.fullPath}`)
// 方式2: 使用refresh_token换回新的token再继续使用, JS代码实现, 用户无感知(效果好)
}
return Promise.reject(error)
})
在请求拦截器上添加,每次请求如果本地有token,就携带token传递过去
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么, 判断一下如果当前本地有token,且请求的响应上没有token
if (getToken()?.length > 0 && config.headers.Authorization === undefined) {
// 发起请求之前, 把token携带在请求头上(表明自己身份)
config.headers.Authorization = `Bearer ' + ${getToken()}`
}
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
这里使用了可选链
完成频道管理的功能,涉及到以下功能
- 频道编辑功能
包括以下
- 编辑频道
- 新增频道
- 更新频道
- 删除频道
- 重置编辑状态
学习到的内容
- 数组方法
fliter方法
findIndex方法
map方法
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1
map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
通过computed计算属性,将还未选中的属性储存成另一个数组
computed:{
unCheckChannelList () {
// 目标: 把所有频道数组挨个对象取出, 去用户已选频道数组里查找, 如果找不到, 则让filter方法收集到一个新数组里
const newArr = this.channelList.filter(bigObj => {
const index = this.userChannelList.findIndex(smallObj => {
return smallObj.id === bigObj.id
})
// 如果找到了
if (index > -1) {
return false
} else {
return true
}
})
return newArr
}
}
- 深拷贝和浅拷贝
接口需要一个对象传过去,在 所有数组里的对象, 都是同一个内存地址, 影响到ChannelEdit.vue中对象
通过浅拷贝(因为只有一层来解决这个问题)
async addChannelFn(channelObj){
this.userChannelList.push(channelObj)
// 问题: 为何只需要push, 不需要从下面数组里移除
// 还要把最新的数组, 发送给后台
// 数组里对象字段 -> 转换
// 推荐频道不能传递-删除出不是推荐频道剩下的频道对象
// const newArr = this.userChannelList.filter(obj => obj.id !== 0)
// newArr.forEach((obj, index) => {
// // delete 对象.属性 可以删除键值对
// delete obj.name
// obj.seq = index
// })
// const res = await updateChannelsAPI({
// channels: newArr
// })
// console.log(res)
// 上面的代码出问题, 新增时, 名字被删除了
// 原因: 所有数组里的对象, 都是同一个内存地址, 影响到ChannelEdit.vue中对象
// 解决方法
// 数组里对象字段 -> 转换
// 推荐频道不能传递-删除出不是推荐频道剩下的频道对象
const newArr =this.userChannelList.filter((obj)=>obj.id!==0)
const theNewArr = newArr.map((obj, index) => {
const newObj = { ...obj } // 拷贝(浅拷贝)
delete newObj.name
newObj.seq = index
return newObj // 让map方法把新对象收集起来形成一个新数组
})
const res =await updateChannelsAPI({
channels: theNewArr
})
},
- v-model绑定数据运用于传递数据
this.$emit('closeEV')
this.$emit('input', obj.id) // 切换
this.
e
m
i
t
和
t
h
i
s
.
emit和this.
emit和this.on传递子组件向父组件通信
this.$ref父组件向子组件通信