vue数据改变了,视图不更新不刷新问题

本文深入探讨Vue.js中数据响应机制的细节,包括如何使用$set方法正确地添加或更新对象属性,确保视图能够实时响应数据变化。同时,文章还讲解了Vue对数组变动的检测限制及解决方案。

vue数据改变了,视图不更新不刷新问题

描述:在对象中添加一个属性 seen,初始想法使用for循环添加 seen 属性,然后改变这个属性去更新视图,然后发现不行。

解决,使用$set:

this.$set(item, 'seen', false)
代码:
// 请求来的数据,在 res.results 中没有seen这个属性,添加这个属性
this.worklogs = res.results
res.results.forEach(item => {
  this.$set(item, 'seen', false)
})
// 改变这个属性来控制显示隐藏
showDesc(log) {
  log.seen = !log.seen
}

对象更改检测

在一个组件实例中,只有在data里初始化的数据才是响应的,Vue不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的。

Vue不允许在已经创建的实例上动态添加根级响应式属性,但是可以使用$set方法将相应属性添加到嵌套的对象上。

已经声明的属性正常响应的,没有声明的属性虽然值发生了改变,console也能打印出来,但并不能响应到视图上。需要用Vue.set(object, key, value) 或 this.$set(object,key,value) 方法将响应属性添加到嵌套的对象上。

注意:object 必须是在data中已经声明的对象。

// this.form.testB = 'desc' // 无效
this.$set(this.form,'testB ','desc') // 动态添加
// 或者 Vue.set(vm.form,'testB ','desc')

Object.assign方法,向嵌套对象上添加多个属性。object.assign方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,并返回目标对象。

语法:vm.object = Object.assign( { } , vm.object , {a:' 1 ', b:' 2 ' }) 

注意:object 必须是在data中已经声明的对象。

this.form1 = Object.assign({}, this.form1, {f1:'f1',f2:'f2'})

数组更改问题

vue检测不到变动问题:1、利用索引直接设置一个项;2、修改数组长度。

1、

changeMe(index) {
  // this.trees[index] = 'xxx' // 无响应
  this.$set(this.trees, index, 'xxx') // 有响应
  // this.trees.splice(index, 1, 'xxx') // 有响应
}
2、
// 改变数组长度
// this.trees.length = 2 // 无响应
this.trees.splice(2) // 有响应

 

感谢作者:

https://www.cnblogs.com/YuKiee/p/9681151.html

在使用 Vue 时,如果出现数据更新视图新的情况,通常与 Vue 的响应式系统机制有关。Vue更新 DOM 时是异步执行的,这意味着当数据发生变化时,Vue 会立即更新 DOM,而是将更新操作放入一个队列中,在下一个事件循环中再执行实际的 DOM 更新。这种机制可以提高性能,避免频繁的 DOM 操作。 ### 解决方案 1. **使用 `Vue.nextTick()` 或 `this.$nextTick()`** 如果需要在数据更新后立即操作 DOM 或确保视图已经更新,可以使用 `Vue.nextTick()` 或 `this.$nextTick()` 方法。该方法接收一个回调函数,该函数将在 DOM 更新完成后执行。 ```javascript this.$set(this.someObject, 'newKey', 'newValue'); this.$nextTick(() => { // 此处可以安全地操作更新后的 DOM }); ``` 2. **使用 `this.$set` 方法更新响应式对象或数组** 当直接给对象添加新属性或修改数组的索引时,Vue 无法检测到这些变化,因此会触发视图更新。此时应使用 `this.$set` 方法来确保新增的属性是响应式的。 ```javascript this.$set(this.someArray, index, newValue); ``` 3. **避免直接通过索引修改数组** Vue 无法检测到通过索引直接修改数组元素的操作。为了确保视图更新,应使用数组的变异方法(如 `splice()`)或 `this.$set` 方法。 ```javascript // 推荐 this.someArray[index] = newValue; // 推荐 this.someArray.splice(index, 1, newValue); ``` 4. **使用 `v-if` 条件渲染** 在某些情况下,如果组件的状态发生变化视图更新,可能是由于组件未被重新渲染。此时可以尝试使用 `v-if` 指令来控制组件的渲染状态,确保在数据变化时重新渲染组件。 ```html <div v-if="isVisible">内容</div> ``` 5. **检查是否在异步操作中修改了数据** 如果在异步操作(如 `setTimeout` 或 `Promise`)中修改了数据,但视图更新,可能是因为 Vue 未能追踪到数据变化。确保在修改数据时使用 Vue 提供的响应式方法,如 `this.$set` 或 `Vue.set`。 6. **强制更新视图** 在极少数情况下,如果上述方法都无法解决问题,可以尝试使用 `this.$forceUpdate()` 方法强制更新视图。但需谨慎使用,因为这可能会导致性能问题。 ```javascript this.$forceUpdate(); ``` ### 总结 Vue 的响应式系统通常能够很好地处理数据视图之间的同步问题,但在某些特殊情况下(如直接修改数组索引或对象属性),需要手动干预以确保视图更新。通过使用 `this.$set`、`this.$nextTick` 或 `v-if` 等方法,可以有效解决数据更新视图新的问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值