Vue踩坑之数据不响应

Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。

如何追踪变化

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty把这些属性全部转为 getter/setter。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

Vue踩坑之数据不响应_第1张图片

默认Vue组件模式的注意事项

如何声明根级响应式属性

默认情况下,Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

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

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

如果你在 data 选项中未声明 message,Vue 将警告你渲染函数在试图访问的属性不存在。

Property or method "message" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

如何动态添加非根级响应属性

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

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

基于类的Vue组件的注意事项

基于类型的Vue组件,可以在在构造初始化时收集所有的类属性到 Vue实例的data中。 因此我们可以用给类定义属性的方式来为Vue实例定义data.

通过this无法修改Vue实例的问题

如果你定义了一个箭头函数类型的属性,并在初始化时访问了this属性,这种方式将无法访问Vue实例。因为this在初始化类属性的过程中,还仅仅是个Vue实例的代理对象,而箭头函数捕获的也是一个代理对象而已。

@Component
class MyComp extends Vue {
  foo = 123

  bar = () => {
    // Does not update the expected property.
    // `this` value is not a Vue instance in fact.
    this.foo = 456
  }
}

这种情况下,你可以简单的定义一个类方法,而不是一个类属性,因为在执行时方法时,this已经指向了正确的Vue实例。

@Component
class MyComp extends Vue {
  foo = 123

  bar () {
    // Correctly update the expected property.
    this.foo = 456
  }
}
未初始化的类属性是非响应的

如果定义类属性时初始化为undefined, 或者根本未初始化(默认也是undefined),那么这个属性将是不能响应的。 你应该将类属性初始化为null或其他有效值,或者用另一种方式:在data里声明一个响应式属性。

@Component
class MyComp extends Vue {
  // Will not be reactive
  foo = undefined

  // Will be reactive
  bar = null

  data () {
    return {
      // Will be reactive
      baz: undefined
    }
  }
}

引用链接

深入Vue响应式原理
vue-class-component

你可能感兴趣的:(Vue踩坑之数据不响应)