vue-初步理解VUE双向绑定原理

vue双向绑定原理

vue的双向绑定是由数据劫持结合发布者-订阅者模式实现。

什么是数据劫持?: vue通过Object.defineProperty()来劫持对象属性的setter和getter操作,在数据变动时做你想要做的事情。

var Book = {
   };

Object.defineProperty(Book,'name',{
   
    set:function(value) {
   
        name = value;
        console.log('你取了名叫:'+value);
    },
    get:function() {
   
        console.log('get方法被监听到');
        return '<'+name+'>';
    }
});
Book.name = '张三';  //你取了名叫: 张三
console.log(Book.name); //<张三>

实现过程

我们已经知道如何实现数据的双向绑定了,那么首先要对数据进行劫持监听,所以我们首先要设置一个监听器Observer,用来监听所有的属性,当属性变化时,就需要通知订阅者Watcher,看是否需要更新。因为属性可能是多个,所以会有多个订阅者,故我们需要一个消息订阅器Dep来专门收集这些订阅者,并在监听器Observer和订阅者Watcher之间进行统一的管理。因为在节点元素上可能存在一些指令,所以我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令初始化成一个订阅者Watcher,并替换模板数据并绑定相应的函数,这时候当订阅者Watcher接受到相应属性的变化,就会执行相对应的更新函数,从而更新视图。

整理上面的思路,我们需要实现几个步骤,来完成双向绑定:

  • Observer 监听器,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
  • Dep 存储依赖和派发更新,监听器和订阅者的桥梁。
  • Watcher 订阅者,可以收到属性的变化通知并执行相应的函数,从而更新视图。
  • Compile 解析器,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器
    在这里插入图片描述

1、实现一个监听器

  • 数据监听器的核心方法就是Object.defineProperty( ),通过遍历循环对所有属性值进行监听劫持监听
  • 在属性的 get里面判断是否需要需要添加订阅者,这是为了让Watcher在初始化时触发
  • 在属性的 set方法中,如果函数变化,就会通知对应的所有订阅者,订阅者们将会执行相对应的更新函数

function Observer(data) {
   
    this.data = data;
    this.walk(data);
}

Observer.prototype = {
   
    walk: function(data) {
   
        var self = this;
        Object.keys(data).forEach(function(key) {
   
            self.defineReactive(data, key, data[key]);
        });
    },
    defineReactive: function(data, key, val) {
   
        var dep = new Dep();
        var childObj = observe(val);
        Object.defineProperty(data, key, {
   
            enumerable: true,
            configurable: true,
            get: function getter () {
   
                //Dep类在下一个文件详细说
                //Watcher初始化触发、判断是否需要添加订阅者明
                if (Dep.target) {
   
                    dep.addSub(Dep.target); //添加订阅者
                }
                return val;
            },
            set: function setter (newVal) {
   
                if (newVal === val) {
   
                    return;
                }
                val = newVal;
                dep.notify(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值