• vue的双向绑定原理解析(vue项目重构二)


    现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会。

    以下也是个人对vue的双向绑定原理的一些浅薄认识,当然 再vue框架的真正实现上,比我分析的要复杂的多。主要是来了解思想

    首先看下下面这段主要代码:

    let data = {price:5,quantity:2};
            let target = null;
            // 一个抽象出来的dep类
            class Dep {
                constructor () {
                    this.subscribers = [];  // 每次调用类时,都会将这个属性更新
                }
                depend() {
                    // 当 target存在 并且没有被订阅
                    if(target && !this.subscribers.includes(target)) {
                        this.subscribers.push(target);
                    }    
                }
                // 循环更新被存储的函数/属性
                notify() {
                    this.subscribers.forEach(sub => sub())
                }
                
            }
            // 循环data的所有属性
            Object.keys(data).forEach(key => {
                let internalValue = data[key];
                // 每个属性获得一个依赖实例
                const dep = new Dep();
                // 对当前data属性描述符 get与set进行数据拦截,进行获取/设置新的data属性值
                Object.defineProperty(data,key, {
                    
                    get() {
                        dep.depend()         // 存储一个当前我们需要进行双向数据绑定数据/函数。
                        return internalValue;   
                    }
                    set(newValue) {
                        internalValue = newValue;
                        dep.notify();    // 重新更新一个存储的函数。
                    }
                })
                
            })
            // 一个只有当企图使用数据双向绑定时才会触发的函数。
            function watcher(myFunc) {
                target = myFunc;
                target();
                target = null;
            }
            
            watcher(() => {
                data.total = data.price * data.quantity;
            }) 

    首先我们来解释一下 我们的vue项目 所有的函数或者是某个被用来做双向数据绑定的值都是绑定在 data 上的,也就是 data.property

    1:dep  一个用来进行数据双向绑定的类,

      a: constructor: 绑定属性,每次进来需要相应双向绑定时 都将目标属性进行重置,用来进行之后的操作。

      b: depend: 这个解释为依赖,可以理解为将目标函数(属性 比如data.name),推进一个全局的存储阵列中。

      c: notify:这个可以解释为更新页面被绑定的数据 执行这个函数,可以将重新设置/输入的属性 发生视图上的变化。

    2:obeject.defiepropoerty()  这个js api接口是实现当数据发生改变时 拦截数据(属性)的。

    该api方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

    // 语法:
    Object.defineProperty(obj, prop, descriptor)
    

      obj要在其上定义属性的对象。

      prop要定义或修改的属性的名称。

      descriptor将被定义或修改的属性。 

      返回值是:被传递给函数的对象。

     简单的描述:

    该方法允许精确添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys 方法), 这些属性的值可以被改变,也可以被删除。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改的。

    如果您能看懂上面的代码运行模式 那么就可以看懂下面的这幅图了,基本思想就是这样。

  • 相关阅读:
    Ubuntu Mysql
    Ubuntu配置大全
    MyEclipse 手动安装 Subclipse 插件
    解决 Ubuntu 11.10 在 RTL8111/8168B 网卡下速度慢的问题
    Ubuntu 多硬盘 LVM 方式安装
    关于编码转换
    Ubuntu 安装时(initramfs) Unable to find a medium containing a live file system错误的解决
    关于 DirectShow 中各个例子的编译转换问题
    ubuntu 中文设置
    javascript 处理鼠标右键事件
  • 原文地址:https://www.cnblogs.com/mamimi/p/9388457.html
Copyright © 2020-2023  润新知