Vue进阶(幺捌陆):异步请求导致页面数据渲染错误问题解决
  Wi5DI2xEMVEE 2023年11月02日 42 0

(文章目录)

一、场景描述

Vue项目优化过程中,页面部分通过JS调用promise返回的异步数据,导致页面部分始终无法加载后台返回的数据。通过触发其他DOM操作(例如折叠栏位的操作),后台数据可以正常渲染展示。处理逻辑大致如下:

<template>
	<div v-for="(items, index) in results" :key="items.itemsID">
		<span v-for="(item, index) in items.appendItems" :key="item.itemID">
			<el-button type="text" @click="handlerClick(item)">
				{{item.itemName}}
			</el-button>
		</span>
	</div>
</template>
<script>
	results.foreach((result, index, results) => {
		results[index].appendItems = []
		aysnMethods(inputParams).then(res => {
			results[index].appendItems = res.returnResults
		})
	})
</script>

二、问题分析

经过页面数据输出及debugger断点调试,发现在页面渲染结束前,异步数据并未处理完毕,导致页面数据渲染问题。

vue实例生成后,再次给对象赋值时,并不会自动更新到视图上去; 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

ES5 限制,Vue.js 不能检测到对象属性的添加或删除,即Vue未做到脏数据检查。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

三、解决措施

通过以上问题分析,可通过v-if控制页面渲染、销毁逻辑,在异步方法请求前销毁相应数据,异步方法请求成功后新建相应数据段。 代码如下:

<template>
	<div v-if="showForm">
		<div v-for="(items, index) in results" :key="items.itemsID">
			<span v-for="(item, index) in items.appendItems" :key="item.itemID">
				<el-button type="text" @click="handlerClick(item)">
					{{item.itemName}}
				</el-button>
			</span>
		</div>
	</div>
</template>
<script>
	data(): {
		return {
			showForm: false
		}
	}
	results.foreach((result, index, results) => {
		results[index].appendItems = []
		vm.showForm = false
		aysnMethods(inputParams).then(res => {
			results[index].appendItems = res.returnResults
			vm.showForm = false
		})
	})
</script>

后经过实践发现,另一种解决方式可应用this.$set()实现。

四、拓展阅读

  • 《[Vue进阶(九十八):Vue.set()和this.$set()介绍]》
  • 《[Vue进阶(九十七):vue给对象动态添加属性和值]》
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  gYl4rku9YpWY   2024年05月17日   55   0   0 Vue
  onf2Mh1AWJAW   2024年05月17日   55   0   0 Vue
  3A8RnFxQCDqM   2024年05月17日   46   0   0 Vue
Wi5DI2xEMVEE