zoukankan      html  css  js  c++  java
  • 快速入门vue-render函数

    render 函数,大部分工老油条,应该是比较了解了,但是可能有些初出茅庐的小年轻们,不是很了解,并且严老湿也去网上查阅了一些相关的文章,总结了一下,不够系统,所以今天简单聊一下,循环渐进

    render 函数是什么

    ​ 平常我们写 <template> 里面所使用模板HTML语法组建页面的,其实在 vue 中都会编译成 render 函数,因为vue 中采用的是 虚拟DOM 所以拿到template模板时也要转译成 VNode(virtual node 虚拟节点) 函数

    插一嘴 虚拟DOM真实DOM 的区别

    虚拟DOM不会进行排版与重绘操作 ,虚拟DOM就是把真实DOM转换为Javascript代码,并且真实DOM频繁操作排版、重绘效率相比虚拟DOM 效率会低很多,比如原生操作真实DOM浏览器会从构建DOM树开始从头到尾执行一遍流程。而虚拟DOM是用Object来代表一颗节点,这个Object叫做VNode,然后使用两个VNode进行对比,根据对比后的结果修改真实DOM

    浏览器渲染引擎工作流程

    浏览器渲染引擎工作流程浏览器渲染引擎工作流程

    虚拟DOMVNode又涉及到diff算法,所以我们先暂停这里,开始我们的正文,当然有兴趣的小伙伴们可以去查阅相关资料

    render 函数的使用

    先看看我们平常vue中的写法

    <template>
     <div>
         <h1>严老湿</h1>
        </div>
    </template>

    如果使用render函数将是怎样呢?

    <script>
        export default {
            render(createElement){
                // createElement:
                // 第一个参数是标签名类型必须是String
                // 第二个是属性值 我们后面来讲,类型是Object
                // 第三个是子级虚拟节点 (VNodes) 可以是String|Array
                return createElement('h1',{},"严老湿")
            }
        }
    </script>

    这样我们也是一样的可以实现 template 中的元素

    image-20200906191922514image-20200906191922514

    动态接收参数

    修改以下上面的代码,我们再来试试

    <script>
        export default {
            props:{
                tag:{
                    type:String,
                    requiredtrue
                }
            },
            render(createElement){
                return createElement(this.tag,{},"严老湿")
            }
        }
    </script>

    在父组件中传值给子组件动态切换标签

    <sub-components tag="button"></sub-components>

    image-20200906204253646image-20200906204253646

    原来可以这样操作,那我们在玩点其他的呗

    <script>
        export default {
            props: {
                tag: {
                    typeString,
                    requiredtrue,
                },
                data: {
                    typeArray,
                    required:true
                },
            },
            render(createElement) {
                return createElement(this.tag, {},
                    // 嵌套到 this.tag 元素上
                    this.data.map(item=>
                        createElement('li',{},item.toString())
                    )
                );
            },
        };
    </script>

    父组件传值

    <sub-components tag="ul" :data="data"></sub-components>

    data:["新冠病毒灭活疫苗首次亮相","辽宁副省长卢柯拿下科学大奖","阚清子说朱一龙神秘"]

    看看效果

    image-20200906210340177image-20200906210340177

    createElement 的属性

    我们刚刚使用了createElement的第一个和第三个参数

    现在来看看第二个参数,为什么拿到后面来讲了,因为里面的东西比较多

    嗯?重头戏么

    接着来看看就知道啦

    class

    <script>
        export default {
            props: {
                tag: {
                    typeString,
                    requiredtrue,
                },
                data: {
                    typeArray,
                    required:true
                },
            },
            render(createElement) {
                return createElement(this.tag, {}, 
                    this.data.map(item=>
                        createElement('li',{
                         // 首先上场的是class
                            class:'child-element'
                         // or
                         // domProps
    {className: "child-element"},
                        },item.toString())
                    )
                );
            },
        };
    </script>

    image-20200906211340374image-20200906211340374

    我们给li 标签加上了class之后,可以直接在元素上看到 child-element ,然后想修改样式的呢,直接通过选择器修改就好了,这就不用多说了吧!

    on

    再来看看事件系列

    <script>
        export default {
            props: {
                tag: {
                    typeString,
                    requiredtrue,
                },
                data: {
                    typeArray,
                    required:true
                },
            },
            render(createElement) {
                return createElement(this.tag, {}, 
                    this.data.map(item=>
                        createElement('li',{
                            domProps: {
                                className"child-element"
                            },
                         // 在on中我们可以写需要的事件
                            on:{
                                // 点击事件 点击打印 Pointer Event
                                click:(e)=>{
                                    console.log(e)
                                },
                                // mouseover
            // mouseout
                            }
                        },item.toString())
                    )
                );
            },
        };
    </script>

    打印结果:

    image-20200906212945930image-20200906212945930

    里面还有很多好玩的东西可以去看看 vue2.0 官方文档

    https://cn.vuejs.org/v2/guide/render-function.html#createElement-%E5%8F%82%E6%95%B0

    如 :styleattrsdirectives 等等....

    vue组件

    如果看过 render 源码的同学应该知道,我们刚刚所说的第一个参数 tag 不仅仅可以是标准的html标签。tag 可以分为正常html标签 | vue组件 两类 。之前已经学了html标签,接下来 我们来看看vue组件

    首先我们新建一个 vue 组件

    <template>
        <div>
            {{content}}
        </div>

    </template>

    <script>
    export default {
        props:{
            content:{
                type:String
            }
        }
    }
    </script>

    在render函数页面中引入

    <script>
        // 引入组件
        import Widget from './Widget'
        export default {
            render(createElement) {
                // 传入组件
                return createElement(Widget, {
                    // 传值 content
                    props:{
                        content:"hello CrazyYan"
                    }
                });
            },
        };
    </script>

    ok 返回到页面上,我们已经看到了组件

    image-20200906215011223image-20200906215011223

    我们学到这里,应该知道

    • render函数的作用
    • 它的简单使用方法
    • 几个参数的作用

    参考资料

    https://cn.vuejs.org/v2/guide/

    https://zhuanlan.zhihu.com/p/80113266

    https://blog.csdn.net/yayayayaya_/article/details/80900807

    - END -

  • 相关阅读:
    反转链表 16
    CodeForces 701A Cards
    hdu 1087 Super Jumping! Jumping! Jumping!(动态规划)
    hdu 1241 Oil Deposits(水一发,自我的DFS)
    CodeForces 703B(容斥定理)
    poj 1067 取石子游戏(威佐夫博奕(Wythoff Game))
    ACM 马拦过河卒(动态规划)
    hdu 1005 Number Sequence
    51nod 1170 1770 数数字(数学技巧)
    hdu 2160 母猪的故事(睡前随机水一发)(斐波那契数列)
  • 原文地址:https://www.cnblogs.com/10ve/p/13625033.html
Copyright © 2011-2022 走看看