Vue 数据更新页面视图未渲染 问题

8 篇文章 0 订阅

Vue 数据更新页面视图未渲染 问题

想解决问题,先看官方api

点击查看 Vue 深入响应式原理
这个api很详细的说明了 vue 的数据变化与视图更新的原理,推荐先阅读这篇信息,下面再分享一点自己在项目中实际踩过的一些坑。

总结一下API中的信息

1.一个最重要最基础的要实现响应式,你必须在初始化实例前声明所有根级响应式 property,哪怕只是一个空值。

  对于基础类型数据,只要是你初始化了,后面不管怎么更改数据,都会触发更新对应视图

2.对于对象,每次更改请 直接 更改 根级别的响应式 property,或者 通过 Vue.set(object, propertyName, value) 的方法更改属性。

   在我们平时开发中,最容易出现的就是使用对象时数据已更新,视图未更新。出现这种问题,主要就是更改根级别的响应式property 后 还增加了其他属性。比如:

export default {
	data() {
		treeData: [],
	},
	methods: {
		// 假设这是一个获取 tree 数据接口,data就是tree 数据
		getTree(this.params).then(({data}) => {
			this.treeData = data // 这里就是更改了根级别响应式的 treeData 这个 property
			this.format(data)
		}),
		// 这个树我们需要默认展开每个节点
		format(data) {
			data.forEach(item => { 
				// 这里就是新增了其他(expand)属性,如果后端返回的数据默认有expand 这个属性
				// 这里的修改没什么问题,但是如果没有,就属于新增了属性
				// 需要使用上面api 里提到的
				// Vue.set(item, 'expand', true)
				// 如果不使用Vue.set方法,上面的 this.treeData = data 放到 this.format(data) 下面,更改完后再更改 根级响应property
				item.expand = true 
				item.children && this.format(item.children)
			})
		}	
	}
}

3.数组,常用方法都能触发响应,例如:pushpopshiftunshiftsplice等等,直接通过下标更改和通过length 赋值更改数组长度不能响应。
   如果是数组对象,使用循环方法forEachmap 等循环时,在循环内部 直接通过item.property 更改数据,只要当前数组在根级响应式property 添加了,并且数组内的对象不是通过下标 赋值的 , 都能触发响应(包括更深层次的多维数组对象)。比如:

<template>
  <div class="test-component">
    <button v-for="(item, i) in arr" :key="i" @click="changeHandle(item)">{{item.number}}</button>
  </div>
</template>

<script>
export default {
	data() {
		return{
			arr: [{
				number: 1	
			}],
		}
	},
	created() {
		this.arr.push({ number: 2})
		this.arr[2] = { number: 4}
	},
	methods: {	,
	    changeHandle(item) {
	      item.number++
	    }	
	}
}
</script>

在这里插入图片描述
可以看到,通过默认初始化的数据能自增响应,通过push插入的也能,但是通过下标赋值的就不能触发响应了。
只有在更改前两个数据时触发了响应函数,vue 去对比数据变化,发现第三个数据也变化了,因此第三个数据就在页面上显示出了最新值。
因此上面说的要初始化,只是为了让数据更新能触发响应。所以大家在使用vue时也经常遇到第三个数据点击不变化,触发其他更新响应时才变化。

4.一个不建议使用的方法
   在上面知道了,即使数据变化无法触发更新响应,但是其他更新响应触发了也会检查当前数据变化。
如果实在找不到自己写得代码哪里出了问题,可以使用hack 方法,就是手动在无法响应的地方添加一个data-listen-update 之类的属性,在data 中初始化一个根级响应 property ,每次更改数据就 给这个property 重新赋值,使其触发更新视图检查。如果无效,可以用下面的方法更暴力一点。

exprot default {
	data() {
		return {
			update: true, // update 放到要更新处 的 v-if=“update” 中
		}
	},
	methods: {
		change() {
			// 这里是更改了数据的代码
			this.update = false
			this.$nextTick(() => { this.update = true })
		}
	}
}

这是一个很暴力的方法,不建议使用,实在解决不了再使用吧。

总结

触发更新响应其实就只需要注意几点事情,根级响应property 一定要添加,对象加属性、数组加数据 要使用 Vue.set 方法。
没了,就这么点,是不是很简单。

以上如有疏漏或错误,欢迎指正,谢谢

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值