如果问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 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
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中,哪怕赋值为空