render 函数
从错误提示开始
打开项目入口文件:main.js
之前的 main.js 写法是:
用我们写的 main.js 文件替换项目生成的话,即使引入了 vue ,也会报错的;
意思是:使用了 "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
先引入 Vue 的完整版,再把 template 改成认识的样子,就能正常输出;
使用render()函数
如果一定要使用 vue.runtime.esm.js
这个版本的 Vue呢?
就得先研究一下 render() 函数了:
看输出:
输出的是个函数:f(),这个函数又 return 出一个函数 createElement(),从函数名字看,是一个创建元素的函数;
所以,改下这个函数:
改成箭头函数的写法:这样也能正常运行;
和项目生成的代码对比:效果一样了;
说了这么多,引出两个问题:
1)有了 Vue.js 完整版,还要再用 vue.runtime.esm.js 这个不完整版?
vue.js 完整版包括两个部分:Vue核心和模板解析器;
模板解析器在打包的时候有用,打包完成后就没有用了,带着没有用的代码到生产环境中,只会徒增负担,所以使用 runtime-only 的版本,可以节省空间。
红框中的 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 做模板;