从数据绑定开始
数据绑定是目前主流前端框架普及的一个重要原因,它们让开发者专注于处理数据而非DOM的实现。Angular是基于scope的脏检查机制,React是组件的state,Vue则是基于Object.defineProperty,今天我们将Vue的数据绑定原理和新API的特性和优势。
Vue是双向绑定吗?
不是,原则上Vue的子组件不能改变父组件传下来的数据(prop),但可以通过v-model这样的语法糖去实现,事实上,Vue和React十分类似,都是采用了单向数据流,这样做更有利于状态的追踪和管理。
Vue如何实现数据绑定
可以分成2部分:数据监听=>数据映射
映射很好理解,数据传入模板或者render函数编译成虚拟DOM,虚拟DOM保存了节点的标签(如div h3等)、绑定的数据(data、methods、props、computed等)以及子节点/关联节点,再根据虚拟DOM的信息映射成真实DOM
数据监听基于Object.defineProperty,下面开始着重介绍
Object.defineProperty(以下简称OD)
这是JavaScript定义对象属性的一个api,通过调用该方法,我们可以定义一个对象的属性及属性描述符,可以理解为属性的属性
Object.defineProperty(object, key, descriptor)
其中,descriptor可以定义如下内容:
详情参考mdn文档
interface PropertyDescriptor {
configurable?: boolean; // 可以对该属性进行删改
enumerable?: boolean; // 是否可以被for in 或者 Object.key迭代获取
value?: any; // 属性值,默认为undefined
writable?: boolean; //是否可以赋值
get?(): any; // 如果定义了getter,当获取到这个属性后,无视默认值,读取getter的返回值
set?(v: any): void; // 对这个属性赋值后触发的回调
}
既然能够通过劫持对象的获取与设置,那么这里边就可以做一些文章了 ,比如我想设计一个高温预警系统,当温度达到40度时发出警告:
const Temperature = {
degree: 28
}
Object.defineProperty (Temperature, 'degree', {
set (value) {
if (value > 40) { alert('高温红色预警!') }
}
})
Temperature.degree = 28 // 不会触发预