Skip to content

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

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 18, 2019 · 7 comments
Labels
vue vue

Comments

@haizhilin2013
Copy link
Collaborator

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

@haizhilin2013 haizhilin2013 added the vue vue label Jun 18, 2019
@Myh-cs
Copy link

Myh-cs commented Jul 9, 2019

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

@HeMin0919
Copy link

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

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

@DanielLeefu
Copy link

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

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

@crush2020
Copy link

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

@hyj443
Copy link

hyj443 commented Oct 27, 2021

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

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

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

@yxllovewq
Copy link

因为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
Copy link

在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
Labels
vue vue
Projects
None yet
Development

No branches or pull requests

8 participants