Skip to content

[vue] 动态给vue的data添加一个新的属性时会发生什么?怎样解决? #284

Open
@haizhilin2013

Description

@haizhilin2013
Collaborator

[vue] 动态给vue的data添加一个新的属性时会发生什么?怎样解决?

Activity

Myh-cs

Myh-cs commented on Jul 9, 2019

@Myh-cs

直接添加属性会因为新的属性没有监听导致页面不能响应该数据的变化。通过vue.$set方法来动态添加响应式属性

HeMin0919

HeMin0919 commented on Jul 28, 2019

@HeMin0919

根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上。

DanielLeefu

DanielLeefu commented on Dec 25, 2019

@DanielLeefu
     对象类型写法
     this.$set("要给哪个对象添加","添加的对象的key",'添加的对象的value')

    数组类型写法
    this.$set('你要修改的数据','你要修改这个数组的索引值',要修改的值val)
crush2020

crush2020 commented on Feb 2, 2021

@crush2020

如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。如果想要使添加的值做到响应式,应当使用$set()来添加对象。

hyj443

hyj443 commented on Oct 27, 2021

@hyj443

因为vue2.x是用的Object.defineProperty去劫持对对象属性的读取和修改的,但无法劫持属性的添加和删除,所以你添加的新属性无法被观测,无法响应式化

但你可 Vue.set(object, key, value)动态的添加响应式属性

而且,data的根属性是不允许动态添加的,要求你初始化定义好,属性值赋值个null什么的
为什么,因为根data属性压根就不是响应式的,即data不是一个响应式对象,vue是不会观测整个data的,它是观测data里定义的属性值对象,

yxllovewq

yxllovewq commented on Mar 10, 2022

@yxllovewq

因为vue2.x是用的Object.defineProperty去劫持对对象属性的读取和修改的,但无法劫持属性的添加和删除,所以你添加的新属性无法被观测,无法响应式化

但你可 Vue.set(object, key, value)动态的添加响应式属性

而且,data的根属性是不允许动态添加的,要求你初始化定义好,属性值赋值个null什么的 为什么,因为根data属性压根就不是响应式的,即data不是一个响应式对象,vue是不会观测整个data的,它是观测data里定义的属性值对象,

题目问的是data新添属性,不是data里面已经被监听的对象或数组新添值,两者不同:

  1. data新添属性无法被监听是因为在vue实例初始化时,vue会将data里的所有属性进行监听,而后面再给data添加的属性没有被vue进行监听处理过。
  2. 如果给data里已经被监听的对象或数组新加一个属性时,由于它们是通过Object.defineProperty的get和set实现监听,只能对读和修改进行拦截,而无法拦截到新增。这也是vue3.0换了Proxy重新实现数据和视图的绑定的原因之一,Proxy可以代理新增和删除操作。
Cai-zhiji

Cai-zhiji commented on Jul 7, 2023

@Cai-zhiji

在Vue中,当动态给Vue实例的data对象添加一个新的属性时,新添加的属性不会自动成为响应式的,也不会触发视图的更新。这是因为Vue在实例化时会对data对象进行响应式处理,只有已经存在的属性才会被转换为响应式,而后添加的属性则不会被Vue追踪。

添加动态响应式属性

Vue.set 或 this.$set 方法:

使用Vue.set方法或this.$set方法可以向Vue实例的响应式对象中添加属性,并确保新属性是响应式的。这样添加的属性会被Vue追踪,当属性值发生变化时会触发视图的更新。

// 使用Vue.set
Vue.set(this.dataObject, 'newProperty', 'new value');

// 使用this.$set
this.$set(this.dataObject, 'newProperty', 'new value');

通过直接赋值或 Vue.observable:

如果想动态添加属性的对象不是Vue实例的data对象,可以使用直接赋值或Vue.observable方法来创建一个新的响应式对象,并将新属性添加到该对象上。

const newObj = { ...this.dataObject, newProperty: 'new value' };
this.dataObject = Vue.observable(newObj);

动态给Vue的data对象添加新属性时,需要使用Vue.set、this.$set、直接赋值或Vue.observable方法来确保新属性是响应式的,并且在组件中正确引用和使用。这样可以保证新属性的变化能够触发视图的更新。

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

        @haizhilin2013@Myh-cs@hyj443@HeMin0919@DanielLeefu

        Issue actions

          [vue] 动态给vue的data添加一个新的属性时会发生什么?怎样解决? · Issue #284 · haizlin/fe-interview