Skip to content

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

Open
@haizhilin2013

Description

@haizhilin2013
Collaborator

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

Activity

wenyejie

wenyejie commented on Jun 17, 2019

@wenyejie

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

radio-qq

radio-qq commented on Jan 4, 2021

@radio-qq

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

crush2020

crush2020 commented on Feb 2, 2021

@crush2020

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

yxllovewq

yxllovewq commented on Mar 10, 2022

@yxllovewq

由于监听的数据在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

jiefancis commented on Aug 16, 2022

@jiefancis

对象:

  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

Cai-zhiji commented on Jul 7, 2023

@Cai-zhiji

可以监听的场景

数组变化的场景:

当你使用数组的变异方法(如 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @wenyejie@haizhilin2013@Drikold@jiefancis@radio-qq

        Issue actions

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