Vue的特色:响应式原理

如果问vue和react最大的区别,我觉得是响应式状态管理!

一下内容来自vue官网,请移驾前往 https://cn.vuejs.org/v2/guide/reactivity.html

如何追踪变化

如下面的例子,data传递给vue示例时,vue会遍历该此对象的所有属性,并使用Object.defineProperty把这些属性全部转为getter/setter,在属性被访问和修改时通知变化

var vm = new Vue({
  data:{
  a:1
  }
})

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

检测变化注意事项

getter/setter转换的时机:在vue实例初始化时执行,所以属性必须在vue的data对象上存在,才能转换它,这样它才是响应式的

var vm = new Vue({
  data:{
  a:1
  }
})

// `vm.a` 是响应的

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

Vue 不能检测以下变动的数组:

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

举例:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

解决第一类问题:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// 或者 
// vm.items.splice(indexOfItem, 1, newValue)

解决第二类问题:

vm.items.splice(newLength)

Vue 不能检测对象属性的添加和删除:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

想要添加一个属性age:

Vue.set(vm.userProfile, 'age', 27)
// 或者 vm.$set(vm.userProfile, 'age', 27)

想要添加多个属性

// 错误的做法
Object.assign(vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})


// 正确的做法
vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

所以要避免非响应式属性的修改,最好在vue实例创建的时候就声明在data中,哪怕赋值为空

猜你喜欢

转载自my.oschina.net/u/2510955/blog/1816501