Vue的特点:响应式原理

若是问vue和react最大的区别,我以为是响应式状态管理!javascript

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

如何追踪变化

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

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

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

 

检测变化注意事项

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

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

举例:ide

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

 

解决第一类问题:ui

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

 

解决第二类问题:spa

vm.items.splice(newLength)

 

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

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中,哪怕赋值为空

相关文章
相关标签/搜索