极简框架van.js,代码阅读

196 阅读1分钟

前言

最近刷文章的时候看到有大佬在介绍该框架,一百多行的代码基本上实现了框架的基本功能,便尝试阅读一下,对于我这种小趴菜来说还是极为痛苦的。
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>

image.png


在官方的 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中触发更新。通过断点可以清楚的看到结构。
image.png
image.png

结语

确实不造应该怎么去描述这个框架,框架中还有我不太懂的代码,就当是水文推荐了