h函数为什么叫h?
看 vue 源码的时候,提到了snabbdom
,而这个库里有个很重要的函数h
。
我就好奇了,为啥用h
,h
是什么的缩写,表示的到底是什么?
然后就翻到hyperScript
这个词,然后找到了解释
Create HyperText with JavaScript, on client or server
而html
是HyperText Markup Language
的缩写,超文本标记语言,本质是文本,但用的是特殊的标记语言写的,其可以表示 纯文本和媒体资源、表单等其他的非文本,所以是超文本。
那么hyperScript
其实是用 js 创建超文本,这里的超文本特指HTML
,而 JS 里可以用DOM
(document object model)表示HTML
,但 js 本身是有DOM API
的,为什么作者还要写这个库?
举个例子就明白了:
创建这样的结构:
<div class="parent"> <span class="son">颜酱真酷</span> </div>
传统的方式:
function createDiv() { const span = document.createElement("span"); span.className = "son"; const div = document.createElement("div"); div.className = "parent"; div.appendChild(span); return div; }
显然这还是结构简单,属性少的情况,如果很多的话,非常繁琐,而且可读性差。
于是想到了,用简单的语句描述,想要的 DOM 结构,然后用函数统一生成想要的结构
其实一个元素的三斧头:标签名、标签的其他自身信息、子元素
function hyperScript(tagName, attrs, children) { // .... } const h = hyperScript; // 这样执行这个方法就可以生成上面的div了 h("div", { className: "parent" }, h("span", { className: "son" }, "颜酱真酷"));
这样可读性强很多,所以这个库的,h函数
,是用节点的描述(标签名、属性和事件、子元素)去创建真实节点的,并返回这个真实节点。
但 snabbdom这个库是处理vnode
的,所以它的的h函数
,是用节点的描述(标签名、标签的其他自身信息、子元素)创建虚拟节点的,并返回这个虚拟节点。
于是平时看到h 函数的时候,心里的联想是Create Virtual HyperText with JavaScript
。
大白话,h函数就是用节点的描述(标签名、标签的其他自身信息、子元素)创建虚拟节点。
为什么有了 h 函数还要 vnode 函数?
其实 h 函数
,更多的时候,是便于用户传参,用户只需要考虑三个要素:标签名、标签的其他自身信息、子元素。
但是一个vnode
有 6 种属性,其中的 key 是从 data 来的,所以vnode
函数需要 5 个参数,用户调用的话,显然增加理解门槛,所以用h函数
简化了传参,降低调用门槛,而h函数
内部调用vnode
函数生成vnode
h函数的参数最多三个,但只有第一个是必传项,第二个参数和第三个都是可传项,所以内部对各种情况作了判断,已生成正确的vnode
// npm i snabbdom 可以快速在编辑器控制台看下,h三个参数,必填的是第一个,data始终是对象,children可以是数组也可以是字符串 const { h } = require("snabbdom"); console.log(h("div.only-sel")); console.log(h("div.only-data", { name: "demo" })); console.log(h("div.only-text", "qqq")); console.log( h("div.only-text", { key: "data这里设置key" }, [h("span"), "子text"]) );