分析snabbdom — init 方法
最后更新于:2022-04-02 08:12:17
[TOC]
>[success] # 分析init
~~~
1.整个snabbdom 核心就是patch,进行新老虚拟dom比较,因此首先需要看init这里做了什么
,因为init返回值是patch 函数,init 的功能:init(modules, domApi),返回 patch() 函数
2.抛开init 中间其他逻辑,其实主要做的就是将这些钩子函数就是类似vue 的声明周期函数
进行初始化保存init() 在返回 patch() 之前,首先收集了所有模块中的钩子函数存储到 cbs 对象中
~~~
>[danger] ##### init 代码 -- src/snabbdom.ts
~~~
1.下面是init 的代码片段,采用了闭包的方式,思考为什么这里使用的闭包,先看init 的使用
let patch = init([])
let patchOldVnode = patch(newVnode,oldVnode)
patchOldVnode = patch(newVnode,patchOldVnode )
这使用闭包的好处,两次调用patch,他们的配置都是init 传入的参数,因为闭包延长了参数的作用域链
可以让后来的patch 都共享init传入的配置参数
1.1.举个例子
const patch = init(['a', 'b', 'c'])
patch() // [ 'a', 'b', 'c' ]
patch() // [ 'a', 'b', 'c' ]
将这个例子转化成类,可以理解成init函数参数就是初始化构造函数,patch 就是这个对象的一个方法
class Init {
constructor(cfgs) {
this.cfgs = cfgs
}
patch() {
console.log(this.cfgs)
}
}
const init = new Init(['a', 'b', 'c'])
init.patch() // [ 'a', 'b', 'c' ]
init.patch() // [ 'a', 'b', 'c' ]
2.init 函数第一个参数为模块,这些提供的模块会有钩子函数,'hooks'列出了所有的钩子函数,
将这些模块的钩子函数按照'hooks'提供的进行分类'最终构建的 cbs 对象的形式 cbs = { create: [fn1, fn2], update: [], ...}'
~~~
~~~
const hooks: (keyof Module)[] = ['create', 'update', 'remove',
'destroy', 'pre', 'post'
];
export function init(modules: Array < Partial < Module >> , domApi ? : DOMAPI) {
let i: number, j: number, cbs = ({}
as ModuleHooks);
// 初始化转换虚拟节点的 api
const api: DOMAPI = domApi !== undefined ? domApi : htmlDomApi;
// 把传入的所有模块的钩子方法,统一存储到 cbs 对象中
// 最终构建的 cbs 对象的形式 cbs = [ create: [fn1, fn2], update: [], ...
]
for (i = 0; i < hooks.length; ++i) {
// cbs['create'] = []
cbs[hooks[i]] = [];
for (j = 0; j < modules.length; ++j) {
// const hook = modules[0]['create']
const hook = modules[j][hooks[i]];
if (hook !== undefined) {
(cbs[hooks[i]] as Array < any > ).push(hook);
}
}
}
………………
return function patch(oldVnode: VNode | Element, vnode: VNode): VNode {}
}
~~~
';