Vue2(笔记25) - 脚手架 - render函数

时间:2022-12-07 22:57:16

render 函数


从错误提示开始

打开项目入口文件:main.js

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

Vue.config.productionTip = false

new Vue({
render: h => h(App),
}).$mount('#app')

之前的 main.js 写法是:

import app from './app.vue'

new Vue({
el:'#root',
comments:{app},
template:`<app></app>`
})

用我们写的 main.js 文件替换项目生成的话,即使引入了 vue ,也会报错的;

Vue2(笔记25) - 脚手架 - render函数

意思是:使用了 "runtime-only" 的 Vue,这是个不带模块编译能力的版本;

要么使用 render() 函数,要么使用带有模板编译能力的 Vue版本;

先来对比下两个入口文件,再尝试使用这两种方式实现一下;


对比两个入口文件

1)引入的Vue是不同的;

我们写的 main.js 没有引入Vue,是在 index.html 中引入的完整版 vue.js ;

项目引入的 Vue 是 "runtime-only " 版本的 Vue,是个不包含模板编译能力的 Vue版本;这个在Vue包里的  package.json 中可以看到配置项:  ​"module": "dist/vue.runtime.esm.js"​;

2)挂载实例的方式不同;

我们的写法是在实例选项 ​el:'#root'​ 中就指定了关联的DOM元素,模板将会替换挂载的元素;

项目是通过 ​vm.$mount()​ 方法,手动挂载实例关联的DOM,效果一样;

vm.$mount()​ 返回实例本身,所以可以链式调用;

3)创建DOM的方式不同;

我们的写法是使用 template 模板选项,把HTML写在这个模板里了,用来替换挂载的元素;

项目是通过渲染函数 ​render()​ 来达到这个目的,是 template 的替换方案;用了 render() 就不用再引入 el 和 template 了;


使用完整版 Vue

import Vue from 'vue/dist/vue'
new Vue({
template:'<h1>你好</h1>'
}).$mount('#app')

先引入 Vue 的完整版,再把 template 改成认识的样子,就能正常输出;


使用render()函数

如果一定要使用 ​vue.runtime.esm.js​ 这个版本的 Vue呢?

就得先研究一下 render() 函数了:

import Vue from 'vue'
Vue.config.productionTip = false

new Vue({
el: '#app',
render(a) {
console.log(a);
return null
}
})

看输出:

ƒ (a, b, c, d) {
return createElement$1(vm, a, b, c, d, true);
}

输出的是个函数:f(),这个函数又 return 出一个函数 createElement(),从函数名字看,是一个创建元素的函数;

所以,改下这个函数:

new Vue({
el: '#app',
render(fn) {
return fn(App)
}
})

改成箭头函数的写法:这样也能正常运行;

new Vue({
el: '#app',
render:fn=>fn(App)
})

和项目生成的代码对比:效果一样了;

new Vue({
render: h => h(App),
}).$mount('#app')

说了这么多,引出两个问题:

1)有了 Vue.js 完整版,还要再用 vue.runtime.esm.js 这个不完整版?

vue.js 完整版包括两个部分:Vue核心和模板解析器;

模板解析器在打包的时候有用,打包完成后就没有用了,带着没有用的代码到生产环境中,只会徒增负担,所以使用 runtime-only 的版本,可以节省空间。

Vue2(笔记25) - 脚手架 - render函数

红框中的 runtime 版本的 Vue 都比完整版小,可以节省流量;

项目中用到的 runtime.esm 中的 esm 是指: ​es module​,意思是说,使用到 es 中的模块化时,就用这个版本;

2)render() 起到什么作用? 

render() 函数是起到渲染模板的作用,是 template 写法的替代方案;


【关于不同版本的Vue】总结:

1)vue.js 与 vue.runtime.xxx.js 的区别

1、vue.js 是完整版的 Vue,包含:核心功能+模板解析器;

2、vue.runtime.xxx.js 是运行版的 Vue,只包含:核心功能,没有模板解析器;

2)因为 vue.runtime.xxx.js 没有模板解析器,所以不能使用 template 配置项,需要使用 render 函数接收到的 createElement 函数去指定具体内容。

一个项目中,一般只使用一次 render() 函数;其他组件的部分都还是使用 template 做模板;