前言
-
vue绝大多数情况下都是使用
<template>
模板来创建HTML的,但是也可以使用渲染函数render
来生成HTML -
render
函数的作用render
函数其实就是用来代替<template>
来生成html的render
函数通过返回一个createElement()
方法生成template模板,这个方法是render
函数自带的createElement
参数传递给它的createElement()
函数有三个参数,分别提供标签名,标签相关属性,标签内部的html内容- 通过这三个参数,可以生成一个完整的HTML
-
在Vue2.0之前,创建一个vue项目,
main.js
里都会有这样一段代码import App from './App.vue' new Vue({ el: '#app', components: { App }, template: '<App/>' })
-
上面的意思就是生成了一个vue实例,然后把这个实例挂载到id为
app
的节点上了,这个节点在项目的index.html
里, -
components
就是注册了APP
这个组件,相当于声明引入的APP
组件 -
template
后面的表示要用到的模板,template: '<App/>'
就表示用<app></app>
替换index.html
里面的<div id="app"></div>
- 官网的描述为
模板将会替换挂载的元素。挂载元素的内容都将被忽略
-
那么按照官网的描述,在渲染生效后,
index.html
的内容就会变成<div id="app"> <app></app> </div>
-
-
Vue2.0后,挂载vue实例就变成了
new Vue({ render: h => h(App) }).$mount('#app')
-
使用
render
代替了上面的components: { App }, template: '<App/>'
来生成组件模板 -
这里的
render: h => h(App)
是ES6的写法,完整写法如下render: function (createElement) { return createElement(App); }
// ES6写法 render: createElement => createElement(App)
- 这里用h代替createElement,使用箭头函数来写
- 尤雨溪在一个回复中提到
- h来自单词 hyperscript,这个单词通常用在 virtual-dom 的实现中。Hyperscript 本身是指生成HTML 结构的 script 脚本,因为 HTML 是 hyper-text markup language 的缩写(超文本标记语言)
- 尤雨溪在一个回复中提到
- 这里用h代替createElement,使用箭头函数来写
-
-
以上是平时最常见的
render
函数的用法
createElement
参数
-
createElement
函数包含了三个参数-
第一个参数:
- 类型:
{String | Object | Function}
- 他可以是 一个 HTML 标签名、组件选项对象,或者resolve 了上述任何一种的一个 async 函数
- 必填项
render(createElement){ // 1. 第一个参数为标签名 return createElement('h1', {}, 'Hello'); // 2. 第一个参数为组件对象,Test为传过来的组件 return createElement(Test, {}, 'Hello'); // 3. 第一个参数为props属性 // 通过props传递标签 props:{ tag:String }, return createElement(this.tag, {}, 'Hello'); }
- 类型:
-
第二个参数:
- 类型:{Object}
- 他可以是一个与模板中 attribute 对应的数据对象
- 可选
return createElement(Test, { // 在组件Test中接收并显示msg的内容 props: { msg: '我是测试2' } });
-
第三个参数:
- 类型:{String | Array}
- 子级虚拟节点 (VNodes),由
createElement()
构建而成, - 也可以使用字符串来生成“文本虚拟节点”
- 可选
// 1. 为数组的情况下,循环遍历数组通过 `createElement()` 构建子节点 // 这里生成的子节点时,createElement的第二个参数还给子节点添加了类名和点击事件 data(){ return{ people:['1', '2', '3'] } }, return createElement('ul', {}, this.people.map(item => createElement('li', { attrs: {class: 'test'}, on: { click: () => {console.log('li click');} } }, item))); return createElement('h1', {}, [ '先写一些文字', createElement('h1', '一则头条'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ]); // 2. 使用字符串来生成“文本虚拟节点” return createElement('h1', {}, 'Hello');
-
示例
-
比如,要把组件
Test.vue
模板里写的<h1>Hello</h1>
在页面上显示一个出来,需要在App.vue
文件中引入Test.vue
-
Test.vue
要生成的HTML也是包裹在template
模板中的<template> <h1>Hello</h1> </template>
-
这时候不想在
template
模板中写html了,想改成写在render
函数里,就可以这样写<script> export default { name: 'Test', render(createElement){ return createElement('h1', {attrs: {class: 'test'}},'Hello'); } } </script>
-
得到的效果是一样的,并且还给
<h1>
添加了一个class