遇到问题
描述:
列表页面,请求方法通过 mixins 混入(写在 mixins 生命周期 created 中),但是需要对渲染数据进行处理(如 code:1 => code:'限位栏'),应该如何执行这个操作呢?
尝试:
- 在组件 created/mounted 函数中对请求到的列表数据 tableData 做处理。失败,原因是,请求数据的操作是异步的,当执行生命周期函数 created 或 mounted 时,该异步操作还未完成,因此访问到的 tableData 是 null。
- 在 mixins 中,对 created 函数加上 async/await。失败。
最佳实践:
- 通过在 mixins 文件中提供一个 func 入口(定义一个 func 字段)用于对请求接口完毕后做其他处理,然后在组件 data 中定义具体的 func 字段来覆盖 mixins 中的 func,实现特异化
接着在请求方法内,请求接口之后,调用这个 func 函数
这样即可确保修改能在获取到数据之后,而且这样也 使得 mixins 具有通用性,当其他组件不想使用该方法时,不传即可,当其他组件具有特殊需求时,可以通过定义特定的方法来修改请求接受的数据
- 也可以通过在组件内使用 watch,监控 tableData 的变化,当其发生变化时,就对其中的数据字段进行处理。这里要注意:
- 我们需要使用另一个新数组来接收处理后的 tableData,否则会出现死循环的情况(即若在 tableData 自身上做处理,则其一直在变化)
- Array.prototype.map() 方法是不会改变数组本身的,而是返回一个新的数组
知识点:
1. mixins 文件中定义的 字段/方法/钩子函数 与引入到的组件中 字段/方法/钩子函数 的优先级顺序
- 对于 data 中定义的字段,组件内的同名字段覆盖 mixins 中的字段
- 对于 methods 中定义的方法,组件内的同名方法覆盖 mixins 中的方法
- 对于 created、mounted 等生命周期函数,vue 会将这两个同名的生命周期函数合成一个新的生命周期函数,mixins 文件中的代码先执行,组件中的后执行
2. vue 生命周期函数能使用 async/await 吗?
- 可以
async created() {
// 需要等到上个代码执行完拿到值再做其他操作
await this.userData(); //这里可以拿到userType
//拿到userType 判断用户不是代理人展示不同信息
if(this.userType==1){
this.isAgent=true;
}
}
注意点:
- 钩子函数只会在指定时间执行(Vue生命周期),使用延时器等是不会影响周期执行的
async created() {
await setTimeout(() => {
console.log(1);
}, 100);
console.log(2);
},
async mounted() {
await setTimeout(() => {
console.log(3);
}, 100);
console.log(4);
}
// 输出结果: 2 4 1 3
// 结论: 所以await 加给setTimeout是没有生效的,延时器并没有影响生命周期执行
- 钩子函数里使用 async/await,后面只能跟 promise,否则加 async/await 没有意义(aysnc 函数都会返回 promise,即使没有写 return)
- 想要同步执行代码,代码必须放在同一个生命周期函数里
data() {
return {
name: ''
}
},
async created() {
// this.userInfo() 发送请求获取数据,然后赋值给this.name ---- this.name = res.data.name
await this.userInfo()
...
},
mounted() {
console.log(this.name) // 打印为''
}
// 结论: 不要以为mounted就一定比created后执行, 因为created加了async,await
// mounted函数懒得等他伺候promise 就先执行了
// 所以你在mounted里面不一定能拿到this.name进行赋值! 所以像这种有依赖上一个代码结果的最好写在一堆
------------------------------------------------------------------------------------
async created() {
// this.userInfo() 发送请求获取数据,然后赋值给this.name ---- this.name = res.data.name
await this.userInfo() // 拿到数据赋值成功
console.log(this.name) // 打印成功
},