Skip to content

[vue] 分别说说vue能监听到数组或对象变化的场景,还有哪些场景是监听不到的?无法监听时有什么解决方案? #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
haizhilin2013 opened this issue Jun 16, 2019 · 8 comments
Labels
vue vue

Comments

@haizhilin2013
Copy link
Collaborator

[vue] 分别说说vue能监听到数组或对象变化的场景,还有哪些场景是监听不到的?无法监听时有什么解决方案?

@haizhilin2013 haizhilin2013 added the vue vue label Jun 16, 2019
@wenyejie
Copy link

能监听是因为已经对该数据设置了observe, 反正则监听不到
$set

@DZ-study
Copy link

DZ-study commented Jul 6, 2020

@radio-qq
Copy link

radio-qq commented Jan 4, 2021

无法监听时的方案:
数组:改变数组的值:this.$set()
改变数组长度:arr.splice()
对象:改变原有属性:Object.assign()
增加新属性:this.$set()

@crush2020
Copy link

crush2020 commented Feb 2, 2021

监听不到到使用$set()给对象添加或者修改,向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。详细参数去官网查看使用。

@Drikold
Copy link

Drikold commented Jul 25, 2021

@yxllovewq
Copy link

yxllovewq commented Mar 10, 2022

由于监听的数据在vue实例新建时就已经确定,且由于是通过Object.defineProperty的get和set实现,因此数组和对象都无法直接监听到添加、删除操作。

数组:

  • 能监听:
  1. 修改数组某个值
  2. 修改数组值
  3. vue对原生的push、pop、unshift、shift、reverse能修改原数组的方法进行进一步封装,使得能够更新视图。
  • 不能监听:
  1. 删除数组某个值
  2. 修改length属性
  3. 使用超过大于arr.length -1的下标对数组添加值
  • 不能监听的解决方案:
  1. 将删除或添加后的数组重新赋值给数组
  2. 使用push、pop等vue对其进一步封装的方法

对象:

  • 能监听:
  1. 修改对象某个属性值
  2. 修改对象值
  • 不能监听:
  1. 新添属性
  2. 删除属性
  • 不能监听的解决方案:将新添和删除后的对象重新赋值给对象

@jiefancis
Copy link

jiefancis commented Aug 16, 2022

对象:

  1. 未在data对象中声明的属性不具备响应式:

data: { a: 1}; data.b = 2。b不具备响应式。可通过this.$set(data, 'b', 2)来赋予data.b响应式

数组:

  1. 非响应式更改:使用索引更改数组中现有元素值 array[index] = newVal
  • 解决方式:this.$set(array, index, newVal)
  1. 非响应式更改:.length 修改数组长度
  • 解决方式:array.splice(newLength)

原因:
Vue对数据的响应式处理在组件创建阶段全量劫持处理,后续在方法中对对象/数组增加新的属性由于并未劫持该属性,所以即使data数据能够读取到新属性的值,但并不会触发页面更新

Vue有哪些api处理响应式
$set Vue.observable

@Cai-zhiji
Copy link

Cai-zhiji commented Jul 7, 2023

可以监听的场景

数组变化的场景:

当你使用数组的变异方法(如 push、pop、splice、shift 等)来修改数组时,Vue能够检测到数组的变化并更新视图。

示例:

this.items.push('new item'); // Vue能监听到数组变化
this.items.splice(0, 1); // Vue能监听到数组变化

对象属性变化的场景:

当你直接修改对象的属性或使用 Vue.set 或 this.$set 方法来添加新的响应式属性时,Vue能够检测到对象的属性变化并更新视图。

示例:

this.obj.message = 'new message'; // Vue能监听到对象属性变化
Vue.set(this.obj, 'newProp', 'new property'); // Vue能监听到对象属性变化

无法监听的场景

直接修改数组索引或对象属性:

如果通过直接修改数组索引或对象属性的方式来进行变化,Vue无法自动检测到变化。

示例:

this.items[0] = 'modified item'; // Vue无法监听到数组变化
this.obj.name = 'modified name'; // Vue无法监听到对象属性变化

解决方案:

对于数组,应该使用变异方法(如 splice)来修改数组,或者使用 this.$set 来更新指定索引的值。
对于对象,应该使用 Vue.set 或 this.$set 来添加新的响应式属性,或者使用 Object.assign 或展开运算符(...)创建新的对象。

通过下标直接修改数组长度:

如果通过修改数组的 length 属性来改变数组的长度,Vue无法自动检测到变化。

示例:

this.items.length = 0; // Vue无法监听到数组变化

解决方案:

应该使用变异方法(如 splice)来修改数组,或者重新赋值一个新的数组来替换原来的数组。

总结来说,Vue能监听到数组或对象变化的主要场景是通过变异方法或特定的操作进行的修改。对于无法监听到的情况,可以使用特定的方法(如 this.$set、Vue.set)或采取其他策略来实现响应式更新。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vue vue
Projects
None yet
Development

No branches or pull requests

9 participants