1.场景:
N层嵌套的循环查询业务场景,框架是vue。其中在最后一层查完之后,还需要查其中每一项的两个属性,类型都是列表。查完之后将其赋值给一个变量用于页面展示。代码如下:
(1)异常代码:
1 getStepRequirement(contentService) { 2 this.contentLoading = true 3 fetchStepRequirement({ 4 id: contentService.contentId 5 }).then(res => { 6 this.contentLoading = false 7 if (res.data.code === 200) { 8 if (res.data.result) { 9 res.data.result.forEach(requ => { 10 // 拼出要求 11 requ['requirementDetail'] = requ.stepRequirementName.replace('%%', requ.stepRequirementData) 12 }) 13 } 14 contentService['requirementList'] = res.data.result || [] 15 16 } else { 17 this.$message({ type: 'error', message: res.data.msg }) 18 } 19 }) 20 } 21 22 this.contentLoading = true 23 fetchStepContent(param).then(res => { 24 this.contentLoading = false 25 if (res.data.code === 200) { 26 step['contentList'] = res.data.result || [] 27 step.contentList.forEach(content => { 28 content.contentServiceLinks.forEach(contentService => { 29 contentService['requirementList'] = [] 30 this.getStepRequirement(contentService) 31 switch (contentService.serviceTypeCode.toLowerCase()) { 32 case 'homework': 33 contentService['homeworkList'] = [] 34 this.getAssignhomeworkById(contentService) 35 break 36 case 'comment': 37 break 38 case 'course': 39 break 40 } 41 }) 42 }) 43 } else { 44 this.$message({ type: 'error', message: res.data.msg }) 45 } 46 }) 47 this.showingContent = step
(2)正常代码:
1 const param = { 2 flag: false, 3 id: step.id 4 } 5 // 是否选课标志 6 if (step.stepTypeCode === 'PSTD1') param.flag = true 7 this.contentLoading = true 8 fetchStepContent(param).then(res => { 9 this.contentLoading = false 10 if (res.data.code === 200) { 11 step['contentList'] = res.data.result || [] 12 step.contentList.forEach(content => { 13 content.contentServiceLinks.forEach(contentService => { 14 contentService['requirementList'] = [] 15 this.getStepRequirement(contentService) 16 }) 17 }) 18 } else { 19 this.$message({ type: 'error', message: res.data.msg }) 20 } 21 }) 22 this.showingContent = step 23 24 25 getStepRequirement(contentService) { 26 this.contentLoading = true 27 fetchStepRequirement({ 28 id: contentService.contentId 29 }).then(res => { 30 this.contentLoading = false 31 if (res.data.code === 200) { 32 if (res.data.result) { 33 res.data.result.forEach(requ => { 34 // 拼出要求 35 requ['requirementDetail'] = requ.stepRequirementName.replace('%%', requ.stepRequirementData) 36 }) 37 } 38 contentService['requirementList'] = res.data.result || [] 39 switch (contentService.serviceTypeCode.toLowerCase()) { 40 case 'homework': 41 contentService['homeworkList'] = [] 42 this.getAssignhomeworkById(contentService) 43 break 44 case 'comment': 45 break 46 case 'course': 47 break 48 } 49 } else { 50 this.$message({ type: 'error', message: res.data.msg }) 51 } 52 }) 53 }
2.原因分析
首先赋值那里,会将showingContent 和step绑定,后边step发生变化之后,会同步变化到showingContent (浅复制问题,不再解释)。但是异常代码中homeworkList和requirementList是并列关系相互独立的,这很符合我们平常的思维模式。但是实际运行结果是,时而只显示了homework,时而只显示了requirement,又时而能都显示出来。具体深层原因暂不完全确定,有知道根本原因的大佬欢迎指教。个人猜想是页面刷新机制方面的问题。因为数据已经都正确了,但是页面未完全刷新。
3.解决方法
解决也有两个:一个就是上边(2)的代码,将其写成依赖关系,实测有效。一个就是在html的相应位置加v-if,然后在查询返回homework和requirement之后分别进行重置if条件来强制刷新。
强制刷新关键代码:
1 this.xxx = false 2 this.$nextTick(() => { this.xxx = true })