您的位置:首页 > Web前端 > Vue.js

用Vue.js实现监听属性的变化

2016-11-17 00:00 986 查看
前言

创建 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
内部首次读取
this.width
this.height
时,Vue 收集其做为
vm.area
的依赖,此后
vm.width
 vm.height
变化时,
vm.area
重新求值。计算属性是基于它的依赖缓存,如果
vm.width
vm.height
没有变化,多次读取
vm.area
,会立即返回之前的计算结果,而不必再次求值。

同样由于
vm.width
vm.height
是响应的,在
vm.area
中可以将依赖的属性赋值给一个变量,通过读取变量来减少读取属性次数,同时解决在条件分支中,Vue 有时会无法收集到依赖的问题。

实现如下:


const vm = new Vue({
data: {
width: 0,
height: 0,
},
computed: {
area () {
let output = ''
const {width, height} = this
if (width > 0 && height > 0) {
const area = width * height
output = area.toFixed(2) + 'm²'
}
return output
}
}
})

vm.width= 2.34
vm.height= 5.67
console.log(vm.area) // 输出 "13.27m²"


通过 ob.js 单独使用 Vue 的属性观察模块

为方便学习和使用,ob.js 将 Vue 中属性观察模块提取并封装了一下。

ob.js GitHub 地址:https://github.com/cnlon/ob.js

安装

npm install --save ob.js


观察属性变化

const target = {a: 1}
ob(target, 'a', function (newValue, oldValue) {
console.log(newValue, oldValue) // 3 1
})
target.a = 3


添加计算属性

const target = {a: 1}
ob.compute(target, 'b', function () {
return this.a * 2
})
target.a = 10
console.log(target.b) // 20


像声明 Vue 实例一样传入参数集合

const options = {
data: {
PI: Math.PI,
radius: 1,
},
computed: {
'area': function () {
return this.PI * this.square(this.radius)
},
},
watchers: {
'area': function (newValue, oldValue) {
console.log(newValue) // 28.274333882308138
},
},
methods: {
square (num) {
return num * num
},
},
}
const target = ob.react(options)
target.radius = 3


总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

您可能感兴趣的文章:

Vue.js每天必学之计算属性computed与$watch
简单理解vue中track-by属性
简单理解vue中Props属性
vue.js入门教程之计算属性
Vue.js教程之计算属性
使用node+vue.js实现SPA应用
基于Vue.js的表格分页组件
Vue.js每天必学之Class与样式绑定
Vue.js每天必学之组件与组件间的通信
强大Vue.js组件浅析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vue.js 属性 监听