vue双向数据绑定

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将数据渲染到页面

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容