前言
最近刷文章的时候看到有大佬在介绍该框架,一百多行的代码基本上实现了框架的基本功能,便尝试阅读一下,对于我这种小趴菜来说还是极为痛苦的。
github.com/vanjs-org/v…
结构
Demo
<script type="module">
import van from "./src/van.js";
debugger
const { button, div } = van.tags;
const counter = van.state(0)
const Counter = () => {
return div(
{
id: 'div',
style: () => `font-size: 16px;margin-top: ${counter.val}px`
},
[
"❤️ ", counter, " ",
button({onclick: () => ++counter.val}, "👍"),
button({onclick: () => --counter.val}, "👎"),
() => {
if (counter.val) {
return 1111
}
return 2222
}
]
)
}
van.add(document.body, Counter())
</script>
在官方的
demo实现一个计步器,引出了div,button函数创建dom,支持样式的动态化。
DOM
基于函数式的dom,作者这里用proxy代理了一个函数。通过bind 将属性名传递的自身函数内部。通过document.createElement(name)创建实例。args[0],即为调用函数的第一个参数,作为dom的props
let tagsNS = ns => new Proxy((name, ...args) => {
let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args]
let dom = ns ? doc.createElementNS(ns, name) : doc.createElement(name)
for (let [k, v] of Obj.entries(props)) {
let getPropDescriptor = proto => proto ?
Obj.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) :
_undefined
let cacheKey = name + "," + k
let propSetter = propSetterCache[cacheKey] ??
(propSetterCache[cacheKey] = getPropDescriptor(protoOf(dom))?.set ?? 0)
let setter = propSetter ? propSetter.bind(dom) : dom.setAttribute.bind(dom, k)
let protoOfV = protoOf(v ?? 0)
if (protoOfV === stateProto) bind(() => (setter(v.val), dom))
else if (protoOfV === funcProto && (!k.startsWith("on") || v._isBindingFunc))
bind(() => (setter(v()), dom))
else setter(v)
}
return add(dom, ...children)
}, {get: (tag, name) => tag.bind(_undefined, name)})
states
这里实现响应式和其他的框架是一样的,通过发布订阅者模式.收集依赖。在set中触发更新。通过断点可以清楚的看到结构。
结语
确实不造应该怎么去描述这个框架,框架中还有我不太懂的代码,就当是水文推荐了