9:Render函数

Posted linbudu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9:Render函数相关的知识,希望对你有一定的参考价值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="Vue.2.6.10.js"></script>
</head>
<body>
    <!-- 写在前面:虚拟dom,是一个轻量级的js对象,在状态发生变化时,进行Diff运算,对比,生成补丁对象,并更新DOM节点,
    与传统dom操作相比,其是基于js计算的,所以开销会少上不少。 -->
    <div id="app1">
        <ele></ele>
    </div>

    <div id="app2">
        <ele2></ele2>
    </div>

    <div id="app3">
        <ele3></ele3>
    </div>

    <div id="app4">
        <ele4></ele4>
    </div>

    <div id="app5">
        <ele5>
            <div>
                <child5></child5>
            </div>
        </ele5>
    </div>
</body>
<script>
    //Vnode对象通过一些特定的选项,描述了真实的dom结构
    var vNode = 
        tag:div,
        attributes:
            id:container
        ,
        children:
            //...
        
    ;
    // 一个render函数的例子

    Vue.component(ele,
        render(createElement) 
            return createElement(
                div,
                //可选的数据对象,包括style、props、dom属性、on、nativeOn(仅对于指令,用于监听原生而非$emit事件)、自定义指令、作用域slot、具名slot等
                    class:
                        show:this.show//动态绑定class
                    ,
                    attrs:
                        id:element//html特型
                    ,
                    on:
                        click:this.handleClick//给div绑定click事件
                    
                ,
                文本内容
            )
        ,
        data() 
            return 
                show:true
            
        ,
        methods: 
            handleClick:function()
                console.log(clicked!);
            
        ,
    );

    var app1 = new Vue(
       el:"#app1" 
    );

    //在所有组件树中,如果vNode是组件或含有组件的slot,那么vnode必须唯一,以下给出两个错误示例
    var childCom =
        render:function(createElement)
            return createElement(p,text)//省略数据对象形式,渲染结果为<p>text</p>
        
    ;
    Vue.component(ele2,
        render:function(createElement)
            //创建一个子节点(使用子组件childCom)
            var childNode = createElement(childCom);
            return createElement(div,[
                childNode,
                childNode
            ])//子节点的传入形式可以是字符串或者数组

        
    );
    var app2 = new Vue(
       el:"#app2" 
    );


    //错误示例2,重复使用含有组件的slot
    Vue.component(child,
        render:function(createElement)
            return createElement(p,text);
        
    );
    Vue.component(ele3,
        render(createElement) 
            createElement(div,[
                this.$slots.default,
                this.$slots.default
            ])
        ,
    );
    var app3 = new Vue(
       el:"#app3" 
    );


    //这两个实例中都在组件里使用了重复的vnode,
    // 第一种情况vnode是局部注册的组件,第二种
    //是含有组件的slot(复习:即<div></div>部分,使用$slots.default访问得到,其内部又含有组件)

    //正确的重复渲染多个组件的方法:
    var child4 = 
        render:function(createElement)
            return createElement(p,"text");
        
    ;
    Vue.component(ele4,
        render:function(createElement)
            return createElement(div,
            Array.apply(null,//将global对象作为thisObj
                length:5
            ).map(function()
                return createElement(child4);
            ))
        
    );
    var app4 = new Vue(
       el:"#app4" 
    );

    //对于带有组件的slot,复用需要将slot的每个子节点都克隆一份
    Vue.component(child5,
        render:function(createElement)
            return createElement(p,text);
        
    );
    Vue.component(ele5,
        render:function(createElement)
            //深度克隆slot节点
            function cloneVNode(vnode)
                const clonedChildren = vnode.children && 
                vnode.children.map(function(vnode)
                    return cloneVNode(vnode);
                );//返回的是vnode数组对象
                console.log(clonedChildren);
                const cloned = createElement(
                    vnode.tag,//‘div’
                    vnode.data,//object
                    clonedChildren//子节点(数组/字符串形式)
                );
                cloned.text = vnode.text;//克隆节点的关键属性值等于传入的slot子节点的关键属性
                cloned.isComment = vnode.isComment;
                cloned.componentOptions = vnode.componentOptions;
                cloned.elm = vnode.elm;
                cloned.context = vnode.context;
                cloned.ns = vnode.ns;
                cloned.isStatic = vnode.isStatic;
                cloned.key = vnode.key;

                return cloned;
            
            const vNodes = this.$slots.default;
            console.log(vNodes);//<div>...</div>
            const clonedVNodes = vNodes.map(function(vnode)
                console.log(vnode);//在这里slot只有一个子节点,因此遍历也只会遍历这一个
                return cloneVNode(vnode);
            );
            console.log(clonedVNodes);
            //获取slot插槽内的内容(子节点),使用map方法依次执行cloneVnode
            //函数,在该函数中进行关键属性的复制
            return createElement(div,[
                vNodes,
                clonedVNodes,
                clonedVNodes//可以重复
            ]);
        
    );

    var app5 = new Vue(
       el:"#app5" 
    );

    
</script>
</html>

 

以上是关于9:Render函数的主要内容,如果未能解决你的问题,请参考以下文章

render函数

Render函数

render函数

iview render函数常用总结(vue render函数)

ReactDom.render函数

Vue - 渲染函数render