render函数是什么

我心飞翔 分类:javascript

前言

上一篇博客我谈到创建vue脚手架选择Runtime-Compiler和Runtime-only的区别
image.png
这篇博客对Runtime-only中vue脚手架中main.js里的vue实例函数中,render函数的作用的学习。

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render: h => h(App)
})
 

在vue实例中render函数的作用

下面代码是使用Runtime-Compiler创建出来的main.js中创建模板的代码,我想将它改造成使用render函数的方法来说明它的使用方法。

new Vue({
  el: '#app',
  components: { App },
  template: '<App/>' 
})
 

下面开始改成render函数:

new Vue({
  el: '#app',
  render:function(createElement) {

  }
})
 

render函数内部接收一个函数叫做createElement函数内容(注意:官方的名字叫“h”,我把它写成createElement更直观一点,这个可以自己命名)。

1. render函数如何使用

createElement函数需要3个参数:

new Vue({
  el: '#app',
  render:function(createElement) {
  // 1.普通用法createElement('标签', {标签的属性},['标签内容'])
  return createElement('h2', {class:'box'},['Hello World'])
  }
})
 

我们来看一下显示结果:

image.png
里面有一个h2的标签,还有一个class=box,还有内容为Hello World。是不是跟我们在createElement函数里的内容一致。createElement函数内容会把挂载的#app内容替换掉!

我们还可以尝试再添加一个按钮:

new Vue({
  el: '#app',
  render: function (createElement) {
    // 1.普通用法createElement('标签', {标签的属性},['标签内容'])
    return createElement('h2', { class: 'box' }, ['Hello World',
      createElement('button', ['按钮'])//增加一个按钮
    ])
  }
})
 

image.png
h2标签里多了一个button按钮!

2. 我们该怎么展示传入的组件对象呢?

直接上代码:

// 创建一个组件
const cpn = {
  template: '<div>{{message}}</div>',
  data(){
    return {
      message:'我是组件message'
    }
  }
}


new Vue({
  el: '#app',
  render: function (createElement) {
    // 1.普通用法createElement('标签', {标签的属性},['标签内容'])
    // return createElement('h2',
    //   { class: 'box' },
    //   ['Hello World',
    //     createElement('button', ['按钮'])//增加一个按钮
    //   ])
    
    // 2.传入一个组件对象:
    return createElement(cpn)
  }
})
 

效果:

image.png
createElement函数可以直接接收一个组件对象,然后把数据渲染到页面上。

3. 传入App组件会有效果吗?

最后我们把import App from './App'的App传入到createElement函数中看看是否有效果。

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
// 创建一个组件
// const cpn = {
//   template: '<div>{{message}}</div>',
//   data(){
//     return {
//       message:'我是组件message'
//     }
//   }
// }


new Vue({
  el: '#app',
  render: function (createElement) {
    // 1.普通用法createElement('标签', {标签的属性},['标签内容'])
    // return createElement('h2',
    //   { class: 'box' },
    //   ['Hello World',
    //     createElement('button', ['按钮'])//增加一个按钮
    //   ])

    // 2.传入一个组件对象:
    return createElement(App)
  }
})
 

效果:

image.png

可以展示,但是有一个疑问。我们来看看App.vue的代码:

image.png
明显这里是有template,但是为什么我们不需要template和ast步骤(关于步骤请看我的《Runtime-Compiler和Runtime-only的区别》博客)呢?因为App.vue文件里的template直接被编译出来就是普通的对象,普通的对象直接转换为render函数了,也就是我们再main.js里拿到的App组件就是没有template的,我们来看一些打印信息:

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

打印一下App
console.log(App);
 

效果:
image.png
没有templatel了,里面多了render函数!这个render就是已经把组件编译成render函数了!

那么.vue文件中的template是由谁处理的了?

是由vue-template-compiler,它会将.vue文件template解析成render函数

App这个组件打印出来是一个被vue-template-compiler解析后的render对象(内部有个render函数)

总结

这样写的好处可以直接省略掉template和ast步骤,直接用render函数编译,可以提高效率。

(关于Vue应用程序是如何运行步骤请看我的《Runtime-Compiler和Runtime-only的区别》博客)

回复

我来回复
  • 暂无回复内容