Vue2:Vue2中不能监听到动态添加的属性-对象

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<body>
<div id="tab">
  <div>{{ textObject }}</div>
  <button @click="addObject">click</button>
</div>
</body>
</html>
<script>
new Vue({
  el: '#tab',
  data: {
    textObject:{
      name:'小红',
      age:[20,30]
    }  
  },
  methods: {
    addObject(){
      this.textObject.sex = "man"
    }
  }
})
</script>
复制代码

image.png
当我们点击button的时候,向Object动态添加sex属性,但页面并未改变。所以说sex属性并未实现响应式

原因:

image.png

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。

所以当我们在页面初始化后去动态向已经创建的实例中添加属性,该属性并未被Vue动态添加根级别的响应式property

解决方法:

可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。

image.png
有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign()_.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
复制代码

声明响应式 property

由于 Vue 不允许动态添加根级响应式 property,所以你必须在初始化实例前声明所有根级响应式 property,哪怕只是一个空值:

var vm = new Vue({
  data: {
    // 声明 message 为一个空值字符串
    message: ''
  },
  template: '<div>{{ message }}</div>'
})
// 之后设置 `message`
vm.message = 'Hello!'
复制代码

如果你未在 data 选项中声明 message,Vue 将警告你渲染函数正在试图访问不存在的 property。
这样的限制在背后是有其技术原因的,它消除了在依赖项跟踪系统中的一类边界情况,也使 Vue 实例能更好地配合类型检查系统工作。但与此同时在代码可维护性方面也有一点重要的考虑:data 对象就像组件状态的结构 (schema)。提前声明所有的响应式 property,可以让组件代码在未来修改或给其他开发人员阅读时更易于理解。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享