vue的数据绑定其实是遵循mvvm思想
01-MVVM开发思想.png
方向一:模型到视图
方向二:视图到模型
底层实现:
双向数据帮定底层原理.png
本次介绍的是es5里面的api接口的Object.getOwnPropertyDescriptor
首先我们知道es5存在delete关键字
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// delete 关键字 用于删除对象的属性
var obj = {id: 1, name: 'andy'};
console.log(obj);
delete obj.id; //删除对象的id属性
</script>
所以我们要思考的是id属性为什么可以删?是有什么决定的?通过es5提供给我们的一个api接口可以查看对象的某个属性相关信息
Object.getOwnPropertyDescriptor
// id 属性为什么可以删除,是由什么决定的? 如何去查看 es5 里面提供一个 api 可以查看对象的某个属性的相关的信息
var des = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(des);
运行结果
image.png
然后,es5底层还有一个api能帮助我们实时监控对象行为。Object.defineProperty( 参数1:代表要监视对象 参数2:代表要监视的属性, 参数3: 对象), 属性:1. set(当我们给对象的属性进行值的设置的时候,这个set方法执行) 2. get 当我们获取对象的属性的时候,get 方法执行。举个例子
<script>
// delete 关键字 用于删除对象的属性
var obj = {id: 1, name: 'andy'};
console.log(obj);
delete obj.id; //删除对象的id属性
// id 属性为什么可以删除,是由什么决定的? 如何去查看 es5 里面提供一个 api 可以查看对象的某个属性的相关的信息
// var des = Object.getOwnPropertyDescriptor(obj, 'name');
// console.log(des);
// 用于监视对象的行为
// 参数1:代表要监视对象 参数2:代表要监视的属性, 参数3: 对象
// 属性:1. set(当我们给对象的属性进行值的设置的时候,这个set方法执行) 2. get 当我们获取对象的属性的时候,get 方法执行
Object.defineProperty(obj, 'name', {
set: function (value) {
console.log(value);// 代表新设置的值
},
get: function () {
return '返回的新值';
}
});
obj.name = '设置值'; // 触发 set 方法执行
console.log(obj.name); // 触发 get 方法执行
</script>
所以在 vuejs 里面,会对 data 模型里面的每个模型变量进行 Object.defineProperty 的调用,为每个模型变量增加一个 get 和 一个 set 用于 拦截数据。然后把数据的处理的权限交给 vuejs 进行处理。处理之后 vuejs 会使用 一个叫做 订阅和发布的(观察者设计) 设计模式来实现页面数据的刷新(渲染)。
这时候问题就来了,什么是订阅,什么又是发布呢??
其实当你每次创建如下模型时
var vm = new Vue({
el: '#box',
data: {
title: '你好', // Object.defineProperty(data, 'title',{set, get})
infos: '消息!', // // Object.defineProperty(data, 'infos',{set, get})
}
});
在vuejs底层都会调用es5的api --Object.defineProperty,为每个data的属性变量创建get和set方法,对数据进行拦截,不会说直接调用set和get的时候就直接显示数据,而是通过插值表达式 <p>{{ title }}</p>写了get方法进行订阅,当数据变化了,底层会通过set将数据渲染到页面
。