VUE的一个数据绑定与页面刷新相关的bug

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 })
原文地址:https://www.cnblogs.com/ljwsyt/p/10734206.html