前言
这里想实现通过subjectId在另一个表中查询这个subjectId所属的major集合,subject表和major表为两个不同的表,通过major_subject表进行关联。
1. 前端页面使用中的问题
1.1 页面中没有显示后端传递的数据
1.2 数据没有及时显示,需要进行刷新
1.3 查错过程
首先检查了后端返回的结果集是否符合规范,在控制台中进行了打印,再在前端开发者工具中通过console.log()
打印了后端传递的数据,发现报错信息:
Type Promise<unknown> is not assignable to type object[] Type Promise<unknown> is not assignable to type Array<object>
出现报错的地方在form表单中的getMajorsBySubjectId()
<el-table :data="getMajorsBySubjectId(row.subjectId)" style="width: 100%">
这里的表单希望接受到一个数组类型而非Promise<Unknown>
类型
寻找解决办法无果后改变了思路:通过@expand-change="handleExpandChange"
监听表单展开,通过data ="props.row.majorList"
进行对表单的赋值。
<el-table :data="props.row.majorList" style="width: 100%">
更改完成后再次对后端返回的majorList[]进行打印,开发者工具中能发现majorList[]中有值,但是前端页面中没有显示数据,再次点击展开发现页面中出现了正确的数据。笔者想到是否需要对展开的表单进行刷新,所以通过v-loading
实现了一个延迟展开,之后就能点击一次展开后就能显示正确的数据。
2. 导致原因
2.1 组件属性
:data
是一个动态属性(也称为 prop),它接收一个数组作为参数,该数组包含了要在表格中显示的数据项。
不同通过 :data = "getMajorsBySubjectId()" 直接传递给:data
初始化表单数据通常通过调用API在 create()、mounted()生命周期钩子中完成
2.2 异步数据更新
handleExpandChange(row) { getMajorsById(row.subjectId).then(majorList => { row.majorList = majorList }) }
由于getMajorsById
是一个异步操作,当数据返回并更新到row
对象时,此时Vue的组件已经重新渲染导致数据不一致或更新丢失。
3. 解决方案
3.1 监听表单展开
通过监听表单展开,获取当前的row.subjectId传递给后端查询,返回值赋值给props.row.majorList
3.2 通过 v-loading 延迟展开操作
通过在data中设置一个 load : false,在监听操作中更新遮罩层,笔者认为自己这种方法并不是最优解决方法,应该还有更好的解决方案
handleExpandChange(row) { this.load = true getMajorsById(row.subjectId).then(majorList => { row.majorList = majorList this.load = false }) }
4. 总结
4.1 组件属性
要掌握组件属性的接受传递值类型限制,掌握常用表单操作的常规做法
4.2 异步数据
要熟知异步数据从产生到使用的过程,熟知异步数据会导致的常见问题:更新丢失、数据不一致、竞态条件等