diff算法(二) snabbdom h函数

h函数

  1. vue中使用h()函数
    new Vue({
    router,
    store,
    render: h => h(App),
    }).$mount(’#app’)
  2. h()函数最早见于hyperscript,使用JavaScript创建超文本
  3. Snabbdom中的h()函数不是用来创建超文本,而是创建VNode

路径./src/h.ts

export function h(sel: string): VNode;
export function h(sel: string, data: VNodeData | null): VNode;
export function h(sel: string, children: VNodeChildren): VNode;
export function h(sel: string, data: VNodeData | null, children: VNodeChildren): VNode;
export function h (sel: any, b?: any, c?: any): VNode {
var data: VNodeData = {}, children: any, text: any, i: number;
if (c !== undefined) {
if (b !== null) { data = b; }
if (is.array©) {
children = c;
} else if (is.primitive©) {
text = c;
} else if (c && c.sel) {
children = [c];
}
} else if (b !== undefined && b !== null) {
if (is.array(b)) {
children = b;
} else if (is.primitive(b)) {
text = b;
} else if (b && b.sel) {
children = [b];
} else { data = b; }
}
if (children !== undefined) {
for (i = 0; i < children.length; ++i) {
if (is.primitive(children[i])) children[i] = vnode(undefined, undefined, undefined, children[i], undefined);
}
}
if (
sel[0] === ‘s’ && sel[1] === ‘v’ && sel[2] === ‘g’ &&
(sel.length === 3 || sel[3] === ‘.’ || sel[3] === ‘#’)
) {
addNS(data, children, sel);
}
// 返回 vnode
return vnode(sel, data, children, text, undefined);
};
export default h;

h函数返回的是一个对象,代表了虚拟dom的关键信息

——————————————————————————————————

补充vue的h()函数

这块是参考红旗下的小兵汇总的

在vue脚手架中,我们经常会看到这样一段代码:

const app = new Vue({
    ··· ···
    render: h => h(App)
})

这个render方法也可以写成这样:

const app = new Vue({
    ··· ···
    render:function(createElement){
        return createElment(App)
    }
  })

h函数就是vue中的createElement方法,这个函数作用就是创建虚拟dom,追踪dom变化的。。。
在看一个例子:写一个main.jsx文件

function getVDOM(){
    return (
        <div id="app">
            <p nameProperty="lxc">my name is lxc</p>
        </div>
    )
}

使用bable编译之后:
在这里插入图片描述
上边代码:最终html代码会被编译成h函数的渲染形式。返回的是一个虚拟DOM对象,通过diff算法,来追踪自己要如何改变真实DOM。

function h(tag,props,...children){//h函数,返回一个虚拟dom对象
    return {
        tag,
        props:props || {},
        children:children.flat()//扁平化数组,降至一维数组
    }
}

我们在看下官方文档所说的createElement函数,它返回的实际上不是一个DOM元素,更准确的名字是:createNodeDescription(直译为——创建节点描述),因为它所包含的信息会告诉vue页面上需要渲染什么样的节点,包括其子节点的描述信息。我们把这样的节点叫做:“虚拟节点(virtual node)”,也常简写为:“VNode”。(看了以上的案例相信在看刚这段话思路会更加清晰)
createElment参数(也就是h函数):
我们还是以官方文档的解释来讲,createElment函数接受三个参数,分别是:

 参数一:tag(标签名)、组件的选项对象、函数(必选);

 参数二:一个对象,标签的属性对应的数据(可选);

 参数三:子级虚拟节点,字符串形式或数组形式,子级虚拟节点也需要使用createElement构建。

来一个小例子:

<!-- 在模板中渲染 -->
<div id="app">
    {{name}}
    <p>{{age}}</p>
</div>
 
 
<!-- 在render函数中渲染 -->
render:function(createElement){
  return createElement("div",{id:"lxc"},[this.name,createElement("p",this.age)])
}

上边代码,值得注意的是,如果父元素有文本内容,在render函数中写的时候,内容写在参数三——数组的第一个参数中。(建议大家动手写一写,理解的会更透彻。)

在来一个官方文档例子:

<!-- 在模板中渲染 -->
<ul v-if="items.length">
      <li v-for="item in items">{{item.name}}</li>
</ul>
<p v-else>No items</p>
 
<!-- 在render函数中渲染 -->
data:{
    items:[{name:"l"},{name:"x"},{name:"c"}]
},
render:function(createElement){
  if(this.items.length){
      return createElement("ul",this.items.map(function(ele){
            return createElement("li",ele.name)
      }))
  }else{
      return createElment("p","No items")  
  }
}

参考:
https://blog.csdn.net/SeriousLose/article/details/119709173
https://blog.csdn.net/qq_42778001/article/details/95959531

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值