JS框架双向数据绑定原理及思考

本文章信息点

  1. 双向数据绑定原理(vue)
  2. 如何设计搭建自己的框架
  3. 代码暂略,详见,github [地址]https://github.com/yyccmmkk/Bi-directionalDataBindingDemo

什么是单向什么是双向?

单向指是数据从model流向view

双向是在单向的基础上数据再从view 流向model。

双向数据绑定原理

相信很多人看过很多双向数据绑定原理相关文章,多半看的一头雾水,看完仍然写不出一个简单的demo 框架,根本不知道为什么要这样做?主要原因是因为没有整理清楚双向数据绑定的需求,因为所有的代码逻辑实现都是围绕需求展开,所以下面会围绕需求展开,再细解如何实现这些需求,从整体逻辑上打通每一环最终实现双向数据绑定框架。所谓万剑归宗、殊途同归,需求是一样的,所以最终的实现也都将大同小异,原理自然而然显现。

简单的说是这样的,

初次模板与数据渲染时,监听数据每个属性的每次调用(通过getter实现),并给其属性添加观察者。监听数据的每个属性变更(通过setter实现),并通知与其相关的观察者,观察者调用自身的更新方法更新view。扫描模板时,找到双向绑定指令,并绑上指定事件,事件触发后更新数据,数据更新触发单向绑定逻辑 view  更新。

说的太简单很多人对细节不清楚,说的细了就是后面的长篇大论了。

相信很多人的疑问有像下面这些的:

观察者只是抽象概念,

  1. 它具体实现是什么?
  2. 为什么同一个属性不只一个观察者?
  3. 又在什么时候添加的?
  4. 观察者添加到哪了?
  5. 每个观察者的更新方法又是怎么确定的?

如何设计实现

单向、双向数据绑定是如何实现的呢?假如现在要写一个双向绑定框架要如何设计呢?

扫描二维码关注公众号,回复: 4864948 查看本文章

单向数据绑定需求可以简单的抽象为:将数据和模板进行某种绑定,数据中的某个属性值发生变化时,属性对应的模板和新值进行处理更新UI(移除旧的UI插入新的UI)。

双向数据绑定需求可以简单的抽象为:在单向的基础上,给特定元素(input 、textarea等)绑定指定事件,并将新值更新到数据,数据更改触发单向数据绑定逻辑,更新UI中相关属性绑定。

通过上面的简单分析,就可以发现"模板"相关需求需要用节点操作来实现,因为需要给特定元素绑定事件,要处理元素中的指令,必定要对模板中每一个节点进行遍历,并对每个节点的属性进行遍历。

下面会逐步分析需求,再将每个需求再细化就可以得到完整的需求,最后实现这些需求。

需求点分析

  1. 将数据的每一个属性与相对应的模板建立联系,数据属性值变更时view进行更新
    • 监听数据所有属性的修改包括值的属性的修改
    • 如何找到属性对应的模板
    • 如何将数据属性与其对应模板建立链接
    • 将数据新值更新到view
  2. 将特定元素的指定事件回馈到数据,数据被修改,同时与些数据相关view更新
    • 监听指定元素的指定事件,并将新值赋值给数据,数据被修改触发view更新逻辑

【1.1解决思路】

数据属性的读写可以通过设置getter setter实现,通过Object.defineProperty()方法设置。 写一个方法递归的处理数据的每个属性不是什么难事。代码暂略,详见,github [地址]https://github.com/yyccmmkk/Bi-directionalDataBindingDemo

【1.2解决思路】

我们需要一个compiler 对模板的每一个节点进行扫描分析,分板当前节点是否有指令(插值表达式、单向数据绑定、双向数据绑定,事件绑定等)。如果有指令,找到当前指令相关的数据属性,当前节点即为'模板'(ps:数据更新时更样的节点)。

【1.3解决思路】

当compiler 对节点分析时如果找到指令,则给该指令相关的属性的更新列表,添加一个watcher实例,该实例包含渲染相关‘模板’(ps:当前扫描到的节点) 

【1.4解决思路】

在1.1中对所有数据属性进行监听时,为每一个属性挂载一个对象(实际上是闭包),该对象拥有一个notify方法,还拥有一个值为数组的list 属性,list 中存放的是当前属性相关的 watcher实例,该实例在1.3(模板解析) 时生成并添加进来,该实例拥有一个update 方法,用来更新view; 当属性值变化时,调用相关必包中的notify 方法,该方法遍历list 中的每一个watcher 实例,并调用该实例的update 方法,upadate方法会在1.3(模板解析)时根据指令生成相关update 方法。本demo 中闭包对象是watcher 类来构造,也可以分开。

以上只是粗枝大叶的整个逻辑分析,细节还有很多,比如:指令解析,管道符解析,指令表达式解析,插槽(用以标记更新时插入点),需要销毁节点等,后续整理出来,计划搞一个系列文章,比如模板指令解析如何进行等,本demo 也有点粗造有时间吧整理一下,以后像虚拟dom的可以搞一搞,像生命周期钩子有了大框架要加也不是很困难,等以后细化再更新。

因精力有限。。。今日到此(未完待续)

猜你喜欢

转载自blog.csdn.net/sflf36995800/article/details/81322447