mvvm框架根源

  • 如果直接在html结构上绑定事件,事件处理函数无法获取到js中的作用域。想要获取T函数的作用域,必须在dom元素上绑定。将模板中的html解析dom树,然后遍历元素上的属性获取事件处理函数的标识,在进行绑定即可。

目前主流框架对事件绑定的实现思想大概有一下三类

1、特定的模板语法,使用Parser解析出来的AST(Abstract Syntax Tree在生成目标Dom树。

2、模板语法使用html,借助innerHTML让浏览器自己生成一个带有模板字符串的fakedomtree再生成DomTree

3、直接将模板内容写在js中,通过预处理的方式将模板字符串转换成虚拟dom解构的js代码,最终全生成DomTree

三类带来的问题

1、parser解析是在浏览器所以有性能问题,首屏渲染卡顿

2、过于依赖于浏览器

3、模板于js写在一起

4、局部更改会引起全页面重新渲染

问题的解决方案

局部更新(只渲染需要更新的地方)

1、将Dom元素与数据绑定在一起

2、对比数据变化前后生成的两个类dom结构树,将改变映射到真是的dom树上

带来的问题

1、观察者模式会会常驻内存,页面的复杂度越高,性能是个大问题

2、数据与dom无法形成绑定,另外一点diff算法至关重要

局部更新使用的检测方式

1、脏检查,主动遍历观察者,判断值是否发生变化

2、懒检测,劫持数据的改变行为,每当行为发生变化,做一次检测

3、不检测,不关心数据,只看前后两个类dom树的变化

 mvvm框架根源ss="headerlink" title="解决方案组合">解决方案组合

脏检查+1
脏检查+2
懒检测+1
懒检测+2
不检测+2

带来的代码结构复用问题

组件化
1、使用类来定义复用组件
组件定义:1、模板 2、状态 3、事件处理函数

123456789101112131415
class  {    constructor(options) {        this._template = options.template;        this._state = options.state || {}    }}//自定义组件
class UserInfo extends  {    constructor(options){        super(options);        Object.assign(this._state, {})    }    nextUser(){}}

确定当前组件使用的作用域

2、使用函数来达到复用的目的
没有模板,也没有作用域的。因为模板在预处理阶段已经被转化成了声明虚拟Dom的js代码。

学习自知乎

相关推荐