前言
创建 Vue 实例时,Vue 将遍历 data 的属性,通过 ES5 的
Object.defineProperty 将它们转为 getter/setter,在其内部 Vue 可以追踪依赖、通知变化。
const vm = new Vue({
data: {foo: 1} // 'vm.foo' (在内部,同 'this.foo') 是响应的
})观察属性变化
Vue 的实例提供了 $watch 方法,用于观察属性变化。
const vm = new Vue({
data: {foo: 1}
})vm.$watch('foo', function (newValue, oldValue) {
console.log(newValue, oldValue) // 输出 2 1
console.log(this.foo) // 输出 2
})
vm.foo = 2
当属性变化后,响应函数将会被调用,在其内部,this 自动绑定到 Vue 的实例 vm 上。
需要注意的是,响应是异步的。
如下:
const vm = new Vue({
data: {foo: 1}
})vm.$watch('foo', function (newValue, oldValue) {
console.log('inner:', newValue) // 后输出 "inner" 2
})
vm.foo = 2
console.log('outer:', vm.foo) // 先输出 "outer" 2
通过
$watch Vue 实现了数据和视图的绑定。观察到数据变化,Vue 便异步更新 DOM ,在同一事件循环内,多次数据变化将会被缓存起来,在下次事件循环中,Vue 刷新队列并仅执行必要的更新。如下:
const vm = new Vue({
data: {foo: 1}
})vm.$watch('foo', function (newValue, oldValue) {
console.log('inner:', newValue) // 后只输出一次 "inner" 5
})
vm.foo = 2
vm.foo = 3
vm.foo = 4
console.log('outer:', vm.foo) // 先输出 "outer" 4
vm.foo = 5
计算属性
MV* 中,将 Model 层数据展现到 View,经常有复杂的数据处理逻辑,这种情况下,使用计算属性 (computed property) 更加明智。
const vm = new Vue({
data: {
width: 0,
height: 0,
},
computed: {
area () {
let output = ''
if (this.width > 0 && this.height > 0) {
const area = this.width * this.height
output = area.toFixed(2) + 'm²'
}
return output
}
}
})vm.width = 2.34
vm.height = 5.67
console.log(vm.area) // 输出 "13.27m²"
在计算属性内部,this 自动绑定 vm,因此声明计算属性时需要避免使用箭头函数。
上例中,
vm.width 和
vm.height 是响应的,
vm.area 内部首次读取









