搞懂vue-render(入門(mén)篇)

render 函數(shù),大部分工老油條,應(yīng)該是比較了解了,但是可能有些初出茅廬的小年輕們,不是很了解,并且嚴(yán)老濕也去網(wǎng)上查閱了一些相關(guān)的文章,總結(jié)了一下,不夠系統(tǒng),所以今天簡(jiǎn)單聊一下,循環(huán)漸進(jìn)

render 函數(shù)是什么

? 平常我們寫(xiě) <template> 里面所使用模板HTML語(yǔ)法組建頁(yè)面的,其實(shí)在 vue 中都會(huì)編譯成 render 函數(shù),因?yàn)?code>vue 中采用的是 虛擬DOM 所以拿到template模板時(shí)也要轉(zhuǎn)譯成 VNode(virtual node 虛擬節(jié)點(diǎn)) 函數(shù)

插一嘴 虛擬DOM真實(shí)DOM 的區(qū)別

? 虛擬DOM不會(huì)進(jìn)行排版與重繪操作 ,虛擬DOM就是把真實(shí)DOM轉(zhuǎn)換為Javascript代碼,并且真實(shí)DOM頻繁操作排版、重繪效率相比虛擬DOM 效率會(huì)低很多,比如原生操作真實(shí)DOM瀏覽器會(huì)從構(gòu)建DOM樹(shù)開(kāi)始從頭到尾執(zhí)行一遍流程。而虛擬DOM是用Object來(lái)代表一顆節(jié)點(diǎn),這個(gè)Object叫做VNode,然后使用兩個(gè)VNode進(jìn)行對(duì)比,根據(jù)對(duì)比后的結(jié)果修改真實(shí)DOM。

瀏覽器渲染引擎工作流程

瀏覽器渲染引擎工作流程

虛擬DOMVNode又涉及到diff算法,所以我們先暫停這里,開(kāi)始我們的正文,當(dāng)然有興趣的小伙伴們可以去查閱相關(guān)資料

render 函數(shù)的使用

先看看我們平常vue中的寫(xiě)法

<template>
    <div>
        <h1>嚴(yán)老濕</h1>
    </div>
</template>

如果使用render函數(shù)將是怎樣呢?

<script>
    export default {
        render(createElement){
            // createElement:
            // 第一個(gè)參數(shù)是標(biāo)簽名類型必須是String
            // 第二個(gè)是屬性值 我們后面來(lái)講,類型是Object
            // 第三個(gè)是子級(jí)虛擬節(jié)點(diǎn) (VNodes) 可以是String|Array
            return createElement('h1',{},"嚴(yán)老濕")
        }
    }
</script>

這樣我們也是一樣的可以實(shí)現(xiàn) template 中的元素

image-20200906191922514

動(dòng)態(tài)接收參數(shù)

修改以下上面的代碼,我們?cè)賮?lái)試試

<script>
    export default {
        props:{
            tag:{
                type:String,
                required: true
            }
        },
        render(createElement){
            return createElement(this.tag,{},"嚴(yán)老濕")
        }
    }
</script>

在父組件中傳值給子組件動(dòng)態(tài)切換標(biāo)簽

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

原來(lái)可以這樣操作,那我們?cè)谕纥c(diǎn)其他的唄

<script>
    export default {
        props: {
            tag: {
                type: String,
                required: true,
            },
            data: {
                type: Array,
                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:["新冠病毒滅活疫苗首次亮相","遼寧副省長(zhǎng)盧柯拿下科學(xué)大獎(jiǎng)","闞清子說(shuō)朱一龍神秘"]

看看效果

image-20200906210340177

createElement 的屬性

我們剛剛使用了createElement的第一個(gè)和第三個(gè)參數(shù)

現(xiàn)在來(lái)看看第二個(gè)參數(shù),為什么拿到后面來(lái)講了,因?yàn)槔锩娴臇|西比較多

嗯?重頭戲么

接著來(lái)看看就知道啦

class

<script>
    export default {
        props: {
            tag: {
                type: String,
                required: true,
            },
            data: {
                type: Array,
                required:true
            },
        },
        render(createElement) {
            return createElement(this.tag, {}, 
                this.data.map(item=>
                    createElement('li',{
                        // 首先上場(chǎng)的是class
                        class:'child-element'
                        // or
                        // domProps: {className: "child-element"},
                    },item.toString())
                )
            );
        },
    };
</script>
image-20200906211340374

我們給li 標(biāo)簽加上了class之后,可以直接在元素上看到 child-element ,然后想修改樣式的呢,直接通過(guò)選擇器修改就好了,這就不用多說(shuō)了吧!

on

再來(lái)看看事件系列

<script>
    export default {
        props: {
            tag: {
                type: String,
                required: true,
            },
            data: {
                type: Array,
                required:true
            },
        },
        render(createElement) {
            return createElement(this.tag, {}, 
                this.data.map(item=>
                    createElement('li',{
                        domProps: {
                            className: "child-element"
                        },
                        // 在on中我們可以寫(xiě)需要的事件
                        on:{
                            // 點(diǎn)擊事件 點(diǎn)擊打印 Pointer Event
                            click:(e)=>{
                                console.log(e)
                            },
                            // mouseover
                          // mouseout
                        }
                    },item.toString())
                )
            );
        },
    };
</script>

打印結(jié)果:

image-20200906212945930

里面還有很多好玩的東西可以去看看 vue2.0 官方文檔

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

如 :style 、 attrs 、directives 等等....

vue組件

如果看過(guò) render 源碼的同學(xué)應(yīng)該知道,我們剛剛所說(shuō)的第一個(gè)參數(shù) tag 不僅僅可以是標(biāo)準(zhǔn)的html標(biāo)簽。tag 可以分為正常html標(biāo)簽 | vue組件 兩類 。之前已經(jīng)學(xué)了html標(biāo)簽,接下來(lái) 我們來(lái)看看vue組件

首先我們新建一個(gè) vue 組件

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

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

在render函數(shù)頁(yè)面中引入

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

ok 返回到頁(yè)面上,我們已經(jīng)看到了組件

image-20200906215011223

我們學(xué)到這里,應(yīng)該知道

  • render函數(shù)的作用
  • 它的簡(jiǎn)單使用方法
  • 幾個(gè)參數(shù)的作用

參考資料

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

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容