Vue 实例的 data 属性

基本认识

  1. 作用:Vue 会递归将 data 的属性转换为 getter/setter 方法,从而使得 data 中属性能够响应数据变化。
  2. 类型: Object | Function
// Object 类型 data 属性
const vm = new Vue({
  data: { 
    name: 'IT白'
  }
}) 

// Function 类型 data 属性
const component = Vue.extend({
  template: '<p>My name is {{ name }}</p>',
  data: function () {
    return {
      name: 'IT白',
    }
  }
})

创建 Object 类型与 Function 类型的data属性的异同

  • 相同点:Vue 都会为其生成相应的 getter/setter 方法。
  • 不同点:当组件被同一时间多次实例化时
      Object 类型:组件的所有实例都会引用同一个数据对象。当一个实例修改的自身的 data 属性,由于引用统一个数据对象,导致修改也将会在其它实例中呈现。
      Function 类型:每次创建组件实例时, Vue 都将通过调用该函数,创建一个全新副本的数据对象。当一个实例修改自身的 data 属性,由于每个实例中的 data 属性对象都是单独的副本,所以不会影响其它实例。

:如果将组件的 data 属性定义为 Object 类型,Vue 会抛出警告。


data 属性响应式原理

追踪数据变化
  • 准备:Vue 会遍历 data 对象(如果是 Function 类型,Vue 会先调用函数,创建对应对象),并将所有属性通过 Object.defineProperty() 转换成 getter/setter
  • collect as dependency:每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。
  • notify:当 setter 被触发时,会通知 watcher。
  • trigger re-render:watcher 重新渲染关联的组件。
  • touch:如果实例修改 data 属性的值,将会触发 setter。
Vue 官方文档插图
检测变化的注意事项

由于 JavaScript 的限制,Vue 无法检测对象属性的添加或删除,所以直接动态添加属性到 data 对象中,该属性为非响应式。

var vm = new Vue({
  data:{
    a:1
  }
})
// `vm.a` 是响应式的

vm.b = 2
// `vm.b` 是非响应式的

但是可以通过 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性,以及 Object.assign() 方法创建一个新的对象。

Vue.set(vm.someObject, 'b', 2)

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
异步更新队列
  • Vue 在更新 DOM 时是异步执行的。
      只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
      如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。
      Vue 在内部对异步队列尝试使用原生的 Promise.thenMutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。

  • 使用 .nextTick()
      为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 使用Vue在日常开发中会频繁接触和使用生命周期,在官方文档中是这么解释生命周期的: 每个 Vue 实例在被创...
    心_c2a2阅读 6,720评论 1 8
  • 这方面的文章很多,但是我感觉很多写的比较抽象,本文会通过举例更详细的解释。(此文面向的Vue新手们,如果你是个大牛...
    Ivy_2016阅读 15,465评论 8 64
  • 前言 Vue.js 的核心包括一套“响应式系统”。 “响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码...
    NARUTO_86阅读 37,693评论 8 86
  • 前言 Vue.js 的核心包括一套“响应式系统”。 “响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码...
    world_7735阅读 4,446评论 0 2
  • 每次看一会书,我就习惯性地拿起手机翻翻朋友圈,或是被其他事情所打扰,总是静不下心来。现在看书的时候,我会把手机放在...
    Linda003阅读 5,288评论 0 0