响应性是 Vue的一个核心特性,用于监听视图中绑定的数据,当数据发生改变时视图自动更新。人们往往对响应性这个术语有一些误解或困惑,会认为响应性就是类似RX之类的响应性编程。但是在这里只要状态发生改变,系统依赖部分发生自动更新就可以称为响应性。在 web应用中,数据的变化如何响应到DOM中,就是Vue解决的问题。
假设我们有个需求,b永远等于a的十倍,如果使用命令式编程,可以很简单实现,可以像下面这样实现,但是当我们把a设置成4时,b还是等于30
let a = 3;
let b = a+ 10;
console.log(b)//30
a = 4
console.log(b)//30
为了让b等于a的10倍,我们需要重新设置b的值:
let a = 3;
let b = a * 10;
console.log(b)//30
a = 4;
b = a * 10;
console.log(b)//40
通过Object.defineProperty修改对象属性的getter和setter让对象具有响应性,这种基于依赖跟踪的方式其实就是vue.js、konckout.js等框架实现的原理。
ES5的Object.defineProperty提供监听属性变更的功能,下面将演示如何通过covert函数修改传入对象的getter和setter实现修改对象属性时打印日志的功能。
function convert (obj) {
// Object.keys获取对象的所有key值,通过forEach对每个属性进行修改
Object.keys(obj).forEach(key => {
// 保存属性初始值
let internalValue = obj[key]
Object.defineProperty(obj, key, {
get () {
console.log(`getting key "${key}": ${internalValue}`)
return internalValue
},
set (newValue) {
console.log(`setting key "${key}" to: ${newValue}`)
internalValue = newValue
}
})
})
}