Vue底层的api——render函数的基本概念和用法

Vue 推荐在绝大多数情况下使用模板(template)来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

平时我们写真实的DOM结构,可以用html编写一个文档,然后提交给浏览器解析成我们想要的页面。同时也可以通过DOM 的api innerHTML告诉浏览器结构是什么,还可以用createElement来构建DOM树,以hello world为例,html和innerHTML api 对DOM结构的描述都是“<h1>hello world</h1>”,但是用createElement就变成了这个样子:

var h1 = document.createElement('h1');
var hw = document.createTextNode('hello world')
h1.appendChild(hw);
document.body.appendChild(h1);

这就是描述一个DOM结构的方式,你可以用一个html文件,一个字符串,或者一段js代码,但是他们都是在做同一件事,就是告诉浏览器该怎么渲染你想要的页面。现在我们回头看vue,在构建vue实例时,我们要写一个叫template的属性,里面是一个html一样的字符串。那么,vue对这个字符串做什么了?事实上,vue拿它构建了虚拟DOM。

render函数

在创建Vue实例的过程中,如果传入的选项中有template和render两个属性,render会有更高的优先级:

new Vue({
    
    
    template:'...',
    render:f(){
    
    }//优先级高
})

这就表示,Vue在看到你要用render函数描述虚拟DOM时。会很高兴,因为它不用自己编译你给他的模板字符串来得到render函数,省力又省心。同时它会丢给你一个函数,这个函数是你构建虚拟DOM所需要的工具,官网上给他起了个名字叫createElement。还有约定的简写叫h,vm中有一个方法_c,也是这个函数的别名。

下面我们先来说说这个构建虚拟Dom的工具,createElement函数。参考官网createElement-参数,首先思考一个普通的html元素会传递给我们哪些信息,
<h1 class='foo'>hello world</h1>,没错,我们可以得到3部分有效信息:

1.这个元素的标签名–h1
2.这个元素有什么属性/事件,class,style,onclick,name,id…
3.这个元素有什么子元素,这里是一个文本节点 ‘hello world’

上面提到,render函数和模板字符串是描述虚拟DOM树的两种方式,那么用createElement函数来描述就变成了下面这样:

craeteElement('h1', {
    
    class,style,on,attrs:{
    
    name,id}, 'hello world'})
//这里,第三个参数还有玄机,接收的参数十分灵活,详情参考官网关于这三个参数的描述

下面我们分别说一下createElement函数的三个参数类型

第一个参数
这个参数是必选,也就是必须要传
参数类型是一个字符串或者一个对象一个函数。像下面这样:

'div'//字符串
{
    
    
    data:{
    
    },
    methods:{
    
    },
    mounted:{
    
    }
}//一个组件选项对象
function(){
    
    return 'div'}//返回上面两种

第二个参数
这个参数可选
一个数据对象,包括对根元素html属性的描述,和组件属性的描述,详情见官网,比方说你要描述这么一个节点:

{
    
    
    'class':{
    
    color:true},
    props:{
    
    height:'1.4m', weight:'50kg'},
    on:{
    
    move:function handle(){
    
    }}
}

第三个参数:
这个参数是可选
可以是一个字符串或者一个数组,数组就表示这个根元素不止有一个虚拟子节点了。还是举个例子:

<h1> <span style="color:red">hello</span> <span>world</span> </h1>

整体来看下面这个例子,就相当于一个h1标签包含了两个span标签,并且打印出,hello world:

vm = new Vue({
    
    
    render:createElement => createElement('h1',[
        createElement('span',{
    
    style:{
    
    color:'red'}},'hello'),
        createElement('span','world')
    ])
});

以上对应的html
<h1>
<span style = "color : red;"> hello </span>
<span>world</span>
</h1>



因为h也可以代表createElement所以,也可以这样写:

render: h => {
    
    
             return h('span',
             ['This is created by ',
             h('a', 'render'),
             ' function'
                        ])
                    }

这个就相当于

<span>
This is created by
<a>render</a>
function
</span>

render函数结合插槽slot数组用会比较方便。
详情看例子vue官网

猜你喜欢

转载自blog.csdn.net/weixin_43902063/article/details/108168947