vue render函数用法怎么用

如何理解Vue的render函数的具体用法
作者:洪定伦
字体:[ ] 类型:转载 时间:
本篇文章主要介绍了如何理解Vue的render函数的具体用法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
本文介绍了如何理解Vue的render函数的具体用法,分享给大家,具体如下:
第一个参数(必须) - {String | Object | Function}
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&elem&&/elem&
ponent('elem', {
render: function(createElement) {
return createElement('div');//一个HTML标签字符
/*return createElement({
template: '&div&&/div&'//组件选项对象
/*var func = function() {
return {template: '&div&&/div&'}
return createElement(func());//一个返回HTML标签字符或组件选项对象的函数*/
el: '#app'
第二个参数(可选) - {Object}
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&elem&&/elem&
ponent('elem', {
render: function(createElement) {
var self =
return createElement('div', {//一个包含模板相关属性的数据对象
'class': {
foo: true,
bar: false
color: 'red',
fontSize: '14px'
domProps: {
innerHTML: 'baz'
el: '#app'
第三个参数(可选) - {String | Array}
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&elem&&/elem&
ponent('elem', {
render: function(createElement) {
var self =
// return createElement('div', '文本');//使用字符串生成文本节点
return createElement('div', [//由createElement函数构建而成的数组
createElement('h1', '主标'),//createElement函数返回VNode对象
createElement('h2', '副标')
el: '#app'
两种组件写法对比
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&ele&&/ele&
/*ponent('ele', {
template: '&div id="elem" :class="{show: show}" @click="handleClick"&文本&/div&',
data: function() {
show: true
methods: {
handleClick: function() {
console.log('clicked!');
ponent('ele', {
render: function(createElement) {
return createElement('div', {
'class': {
show: this.show
id: 'elem'
click: this.handleClick
}, '文本');
data: function() {
show: true
methods: {
handleClick: function() {
console.log('clicked!');
el: '#app'
this.$slots用法
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&blog-post&
&h1 slot="header"&&span&About Me&/span&&/h1&
&p&Here's some page content&/p&
&p slot="footer"&Copyright 2016 Evan You&/p&
&p&If I have some content down here&/p&
&/blog-post&
ponent('blog-post', {
render: function(createElement) {
var header = this.$slots.header,//返回由VNode组成的数组
body = this.$slots.default,
footer = this.$slots.
return createElement('div', [
createElement('header', header),
createElement('main', body),
createElement('footer', footer)
el: '#app'
使用props传递数据
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&ele :show="show"&&/ele&
&ele :show="!show"&&/ele&
ponent('ele', {
render: function(createElement) {
if (this.show) {
return createElement('p', 'true');
return createElement('p', 'false');
type: Boolean,
default: false
el: '#app',
show: false
VNodes必须唯一
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&!-- VNode必须唯一 --&
&div id="app"&
&ele&&/ele&
var child = {
render: function(createElement) {
return createElement('p', 'text');
/*ponent('ele', {
render: function(createElement) {
var childNode = createElement(child);
return createElement('div', [
childNode, childNode//VNodes必须唯一,渲染失败
ponent('ele', {
render: function(createElement) {
return createElement('div',
Array.apply(null, {
}).map(function() {
return createElement(child)//正确写法
el: '#app'
v-model指令
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&el-input :name="name" @input="val=&name=val"&&/el-input&
&div&你的名字是{{name}}&/div&
ponent('el-input', {
render: function(createElement) {
var self =
return createElement('input', {
domProps: {
value: self.name
input: function(event) {
self.$emit('input', event.target.value);
name: String
el: '#app',
name: 'hdl'
作用域插槽
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&template scope="props"&
&span&{{props.text}}&/span&
&/template&
ponent('ele', {
render: function(createElement) {
// 相当于&div&&slot :text="msg"&&/slot&&/div&
return createElement('div', [
this.$scopedSlots.default({
text: this.msg
data: function() {
msg: '来自子组件'
el: '#app'
向子组件中传递作用域插槽
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&ele&&/ele&
ponent('ele', {
render: function(createElement) {
return createElement('div', [
createElement('child', {
scopedSlots: {
default: function(props) {
createElement('span', '来自父组件'),
createElement('span', props.text)
ponent('child', {
render: function(createElement) {
return createElement('b', this.$scopedSlots.default({text: '我是组件'}));
el: '#app'
函数化组件
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&render&/title&
&script src="/vue/2.3.4/vue.js"&&/script&
&div id="app"&
&smart-item :data="data"&&/smart-item&
&button @click="change('img')"&切换为图片为组件&/button&
&button @click="change('video')"&切换为视频为组件&/button&
&button @click="change('text')"&切换为文本组件&/button&
// 图片组件选项
var ImgItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '图片组件'),
createElement('img', {
src: this.data.url
// 视频组件
var VideoItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '视频组件'),
createElement('video', {
src: this.data.url,
controls: 'controls',
autoplay: 'autoplay'
/*纯文本组件*/
var TextItem = {
props: ['data'],
render: function(createElement) {
return createElement('div', [
createElement('p', '纯文本组件'),
createElement('p', this.data.text)
ponent('smart-item', {
functional: true,
render: function(createElement, context) {
function getComponent() {
var data = context.props.
if (data.type === 'img') return ImgI
if (data.type === 'video') return VideoI
return TextI
return createElement(
getComponent(),
data: context.props.data
context.children
type: Object,
required: true
el: '#app',
methods: {
change: function(type) {
if (type === 'img') {
this.data = {
type: 'img',
url: '/iview/iview/master/assets/logo.png'
} else if (type === 'video') {
this.data = {
type: 'video',
url: 'http://vjs.zencdn.net/v/oceans.mp4'
} else if (type === 'text') {
this.data = {
type: 'text',
content: '这是一段纯文本'
created: function() {
this.change('img');
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具近期公司工作较忙,更新一直上不来,望大家见谅。不废话,今天我们来看一下,vue的render函数。
很多朋友对于长篇大论看不下去,有的呢是有接触过这些,所以我们今天吧总结写在前边。需要的朋友可以往下看:
1. render方法的实质就是生成template模板;
2. 通过调用一个方法来生成,而这个方法是通过render方法的参数传递给它的;
3. 这个方法有三个参数,分别提供标签名,标签相关属性,标签内部的html内容
4. 通过这三个参数,可以生成一个完整的木模板
render方法可以使用JSX语法,但需要Babel plugin插件;
render方法里的第三个参数可以使用函数来生成多个组件(特别是如果他们相同的话),只要生成结果是一个数组,且数组元素都是VNode即可;
render函数室友限制的,Vue.js 2.X支持,但是1.X无法使用。
我们接着来,我们今天先来粗略的了解下render函数,后面我会用大量的代码进行说明,便于大家先简单的了解,后边我们在进行深入了解。
什么是render函数呢?Vue官方给我们已经说明。
VUE推荐在绝大多数情况下使用template来创建我们的HTML。然而在一些场景中,我们真的需要JavaScript的完全编程的能力,这就是render函数,它比template更接近编译器。
name="hello-world" href="#hello-world"&
Hello world!
在HTML层,我们决定这样定义组件接口:
&anchored-heading :level="1"&Hello world!&/anchored-heading&
当我们开始写一个通过levelprop 动态生成heading 标签的组件,你可能很快想到这样实现:
ponent('anchored-heading', {
template: '#anchored-heading-template',
type: Number,
required: true
在这种场景中使用 template 并不是最好的选择:首先代码冗长,为了在不同级别的标题中插入锚点元素,我们需要重复地使用&slot&&/slot&。
虽然模板在大多数组件中都非常好用,但是在这里它就不是很简洁的了。那么,我们来尝试使用render函数重写上面的例子:
ponent('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level,
this.$slots.default
type: Number,
required: true
简单清晰很多!简单来说,这样代码精简很多,但是需要非常熟悉 Vue 的实例属性。在这个例子中,你需要知道当你不使用slot 属性向组件中传递内容时,比如 anchored-heading 中的 Hello world!, 这些子元素被存储在组件实例中的 $slots.default中。如果你还不了解, 在深入 render 函数之前推荐阅读实例属性API。
我们来一个生成模板对比,便于学习
非使用render方法的情况下
&div id="app"&
&child :level="1"&Hello world!&/child&
&script type="text/x-template" id="template"&
&h1 v-if="level === 1"&
&slot&&/slot&
&h2 v-if="level === 2"&
&slot&&/slot&
&h3 v-if="level === 3"&
&slot&&/slot&
&h4 v-if="level === 4"&
&slot&&/slot&
&h5 v-if="level === 5"&
&slot&&/slot&
&h6 v-if="level === 6"&
&slot&&/slot&
&script type="text/javascript"&
ponent('child', {
template: '
type: Number,
required: true
el: "#app"
代码说明:
1. 最下面的new Vue方法很明显,是new了一个Vue的实例,挂载点#app这个
2. ponent这部分代码,第一个参数表示注册了一个Vue的组件,标签名是child(即 &child& 标签会被替换);
3. 第二个参数中,template属性表示取找id=“template”的标签(另注,这个标签是&script&,或者是&div&,或者是template,或者是其他,没有影响),然后将这个标签作为组件的模板;
4. props表示传递给这个组件的变量,通过标签中的v-bind:level这种形式传递变量level的值等于1。在这里的写法是限制变量类型为number,并且强制需要;
5. slot表示内容分发,具体来说,就是把组件替换的源html标签里的内容(如 &child& 标签里面的内容,不包含 &child& 标签本身,这里是Hello world!),发在 &slot& 标签所在的位置(即放在&h1&-&h2& 这样的标签内);
6. 如果还不理解,可以运行该段代码查看结果,或者去看vue的官方文档说明;
7. 总的来说,顺序如下:注册一个组件,这个组件有模板,这个模板里有一个变量,变量的值通过父组件来传递,然后根据变量的值,通过v-if命令显示对应的html标签内容,然后在父组件里使用这个组件,让子组件显示需要显示的内容。
这样的代码有一个缺陷,就是需要大量重复的代码。如&h1&~&h6&共六种情况。如果这样的模板比较复杂,比如&hx&标签里还有很多其他内容,显然会让人十分困扰,既不美观又不好用。
使用render方法的情况
v-bind:level="2"&Hello world!&
type="text/javascript"&
ponent('child', {
render: function (createElement) {
return createElement(
'h' + this.level,
this.$slots.default
type: Number,
required: true
el: "#app"
代码说明:
这里的代码和上面区别之处有两点:
其一,没有显式的模板内容,而是通过render方法生成;
其二,使用了createElement方法。
关于createElement方法,他是通过render函数的参数传递进来的,这个方法有三个参数:
第一个参数主要用于提供dom的html内容,类型可以是字符串、对象或函数。比如”div”就是创建一个 &div&标签
第二个参数(类型是对象)主要用于设置这个dom的一些样式、属性、传的组件的参数、绑定事件之类,具体可以参考 官方文档 里这一小节的说明
第三个参数(类型是数组,数组元素类型是VNode)主要用于说是该结点下有其他结点的话,就放在这里。
比如说,有需要分发的标签 &slot&,则通过 this.$slots.default 来获得,或许还有其他组件之类,可能需要被使用的,应该也是放在这里。
个人初步理解是,在原本被替换的地方,例如例上面代码中的 &child& 标签,在其下的每个次一级标签为一个元素,放在 this.$slots.default这个数组中,例如上面的话,这个数组只有一个元素,但是以下代码:
&child v-bind:level="2"&&div&Hello&/div&&div& world!&/div&&/child&
这个数组中则有两个元素,分别是 &div&Hello&/div& 和 &div& world!&/div&例如 this.$slots.default[0] 则表示第一个标签。
另外,假如这2个元素中间有空格、换行符之类,那么数组中则有三个元素,那个空格、换行符则为第二个元素。这个属性有点类似dom的 childNodes属性,不是单纯以标签才算作子节点的。(但注意,不是完全相同)
有时候,我们可能想在里面添加其他的组件,例如将abc组件注册在里面。那么,我们首先要注册这个abc组件,然后将abc组件在数组里通过createElement来创建标签,只有通过这样的方式创建的abc标签,才能被abc组件使用。单纯输入字符串"&abc&&/abc&" 这样是不可以的。
如以下代码也是可行的(在通过render方法生成的模板中添加别的组件):
v-bind:level="2"&
ponent('abc', {
template: "&div&abc&/div&"
ponent('child', {
render: function (createElement) {
console.log(this.$slots)
return createElement(
'h' + this.level,
[this.$slots.default[0], createElement("abc"),
this.$slots.default[1]]
type: Number,
required: true
el: "#app"
显示结果是:
最后,如果想将原有内容全部使用(而不是只取部分标签),那么直接使用 this.$slots.default 作为第三个参数即可,他本身就是一个数组。
总而言之,createElement方法的作用就是动态的创建一个dom用于被render函数渲染,其中参数二和参数三可以选择性省略,参数二用于设置dom的样式、属性、事件等,参数三用于设置分发的内容,包括新增的其他组件。
粗略理解的话,可以理解为:createElement( 标签名, 标签属性, 标签里的内容)。
这样的话,我们就有了一个组件的模板所需要的全部内容了。后边我们在深入的了解下render函数。
本文已收录于以下专栏:
相关文章推荐
首先,我们先了解什么是MVX框架模式?
MVX框架模式:MVC+MVP+MVVM
1.MVC:Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职...
1.github下载地址:/vuejs/vue-devtools
2.下载好后进入vue-devtools-master工程  执行npm install...
1. vue 数据过滤数据过滤,可以通过全局 Vue.filter 定义规则,也可以局部实现过滤。局部过滤: export default {
name: 'app',
尤雨溪之前在微博发布消息,不再继续维护vue-resource,并推荐大家开始使用 axios 。
axios 是一个基于Promise 用于浏览器和...
今天本来是要写一篇技术文章的,可是啊可是,第一天发生的事情太美好,美好的没心情写技术文章了。我来跟大家复盘一下今天发生的事情。
美好的第一天开始
上午也没什么事,就起来洗澡洗漱,扫地拖地打...
注意:vue-router 2只适用于Vue2.x版本,下面我们是基于vue2.0讲的如何使用vue-router 2实现路由功能。
推荐使用npm安装。
npm install vue-rout...
本文采用vue2.0+vuex+localStorage+sass+webpack,实现一个本地存储的记事本。兼容PC端和移动端。在线预览地址: DEMO
支持回车添加事件
入门请参考这篇文章:Vue构建单页应用最佳实战
在此记录下在我使用Vue.js 2.0开发较大型的单页应用时遇到的困难。写文章不容易,如果这篇文章对你有帮助,请给我的github仓库加个star~
/articles/UfeqmaE
使用vue-router 来实现webapp的页面跳转,有时候需要传递参数,做法如下:
参考文献:http://router.vuejs.org/en/named.html 
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)\ Vue2.0文档学习及案例总结之----Render Functions
Vue2.0文档学习及案例总结之----Render Functions
Web前端工程师
志不朽者虽难必易,行不止者虽远必臻!
作者的热门手记
Vue2.0文档学习及案例总结之----Render Functions
以下学习总结,目前对于JSX和functional render尚未全面分析,但大多数常规做法都有了分析,这个将在后继文档中补充。
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&Render&/title&
&script src="/vue/dist/vue.js"&&/script&
&div id="demo"&&/div&
ES6模板字符串
var basket = {count: '8000', onSale: 'Yes'};
document.querySelector('body').append(`
There are &b&${basket.count}&/b& items
in your basket, &em&${basket.onSale}&/em&
are on sale!`
&h4&That template doesn’t feel great.&/h4&
&p&内容分发一般适用于根标签相同内容不同的DOM结构&/p&
&div id=&app&&
&anchored-heading :level=&1&&Hello world!&/anchored-heading&
&anchored-heading :level=&2&&Hello world!&/anchored-heading&
&anchored-heading :level=&3&&Hello world!&/anchored-heading&
&anchored-heading :level=&4&&Hello world!&/anchored-heading&
&anchored-heading :level=&5&&Hello world!&/anchored-heading&
&anchored-heading :level=&6&&Hello world!&/anchored-heading&
&script type=&text/x-template& id=&anchored-heading-template& name=&anchoredHeading&&
&h1 v-if=&level === 1&&
&slot&&/slot&
&p v-if=&level === 2&&
&slot&&/slot&
&h3 v-if=&level === 3&&
&slot&&/slot&
&h4 v-if=&level === 4&&
&slot&&/slot&
&h5 v-if=&level === 5&&
&slot&&/slot&
&h6 v-if=&level === 6&&
&slot&&/slot&
var aa = ponent('anchored-heading', {
template: '#anchored-heading-template',
type: Number,
required: true
el: '#app',
components: {
anchoredHeading: aa
&h4&So let’s try rewriting it with a render function:&/h4&
&h4&理解slot&/h4&
&div id=&slot&&
&blog-post&
&h1 slot=&header&&
&p&Here's some page content, which will be included
in vm.$slots.default, because it's not inside a named
&p slot=&footer&&
Copyright 2016 Evan You
&p&If I have some content down here, it will also be included in vm.$slots.default.&/p&.
&/blog-post&
ponent('blog-post', {
render: function (createElement) {
var header = this.$slots.
var body = this.$slots.
var footer = this.$slots.
return createElement('div', [
createElement('header', header),
createElement('div', body),
createElement('footer', footer)
let slot = new Vue({
el: '#slot'
&div id=&app1&&
&anchored-heading-a :level=&3&&Hello world!&/anchored-heading-a&
&anchored-heading-a :level=&1&&Hello world!&/anchored-heading-a&
&h5&createElement参数详细说明&/h5&
// @returns {VNode}
createElement(
// {String | Object | Function}
// {Object},属性对象,可以在 template 中使用.可选项.
'class': {
foo: true,
bar: false
color: 'red',
fontSize: '14px'
myProp: 'bar'
domProps: {
innerHTML: 'baz'
// 事件监听器基于 &on&
// 所以不再支持如 v-on:keyup.enter 修饰器
// 需要手动匹配 keyCode。
click: this.clickHandler
// 仅对于组件,用于监听原生事件,而不是组件使用 vm.$emit 触发的事件。
nativeOn: {
click: this.nativeClickHandler
// 自定义指令. 注意事项:不能对绑定的旧值设值
directives: [
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
// Scoped slots in the form of
&!--// { name: props =& VNode | Array&VNode& }--&
scopedSlots: {
default: props =& h('span', props.text)
// 如果子组件有定义 slot 的名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
// {String | Array},子节点(VNodes). 可选项.
createElement('h1', 'hello world'),
createElement(MyComponent, {
someProp: 'foo'
&h5&局限&/h5&
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// Yikes - duplicate VNodes!
myParagraphVNode, myParagraphVNode
//如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现
render: function (createElement) {
return createElement('div',
Array.apply(null, { length: 20 }).map(function () {
return createElement('p', 'hi')
//所有组件树中的 VNodes 必须唯一。这意味着,下面的 render function 是无效的:
var ab = ponent('anchored-heading-a', {
render: function (createElement) {
return createElement(
// {String | Object | Function}
// 一个 HTML 标签,组件设置,或一个函数
// 必须 Return 上述其中一个
'h' + this.level,
// tag name
this.$slots.default // array of children
type: Number,
required: true
el: '#app1',
components: {
anchoredHeadingA: ab
&h4&The Data Object In-Depth&/h4&
&h4&Complete Example&/h4&
&div id=&see&&
&anchored-heading-x :level=&1&&&p&&span&&b&Hello world x!&/b&&/span&&/p&&/anchored-heading-x&
var getChildrenTextContent = function (children) {
return children.map(function (node) {
return node.children
? getChildrenTextContent(node.children)
: node.text
}).join('')
ponent('anchored-heading-x', {
render: function (createElement) {
var headingId = getChildrenTextContent(this.$slots.default)
.toLowerCase()
.replace(/\W+/g, '-')
.replace(/(^-|-$)/g, '');
console.log(this.$slots.default);
alert(headingId);
var myParagraphVNode = createElement('p', 'hi');
return createElement(
'h' + this.level,
createElement('a', {
id: 'test',
name: headingId,
href: '#' + headingId
'class': {
foo: true,
backgroundColor: 'red',
}, this.$slots.default)
myParagraphVNode
Render.html?_ijt=4pvp8fv14frqcjnk:230 Uncaught SyntaxError: Unexpected identifier
type: Number,
required: true
el: '#see'
&div id=&app2&&
&anchored-heading-b&&/anchored-heading-b&
var ac = ponent('anchored-heading-b', {
render: function (createElement) {
var that =
return createElement('ol',
Array.apply(null, {length: 3}).map(function () {
return createElement('li', that.msg)
data: function () {
msg: 'hello Array.apply(null,{}.map()'
el: '#app2',
props: ['msg'],
components: {
anchoredHeadingB: ac
&h4&Replacing Template Features with Plain JavaScript&/h4&
&div id=&app3&&
&i&render rendering&/i&
&anchored-heading-c&
&/anchored-heading-c&
&i&list rendering&/i&
&ul v-if=&items.length&&
&li v-for=&item in items&&{{ item.name }}&/li&
&p v-else&No items found.&/p&
var ad = ponent('anchored-heading-c', {
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item.name)
return createElement('p', 'v-else:No items found.')
data: function () {
items: [{name: 'v-if:hello'}, {name: 'hello'}, {name: 'hello'}, {name: 'hello'}, {name: 'hello'}]
el: '#app3',
data: function () {
items: [{name: 'world'}, {name: 'world'}, {name: 'world'}, {name: 'hello'}, {name: 'hello'}]
components: {
&b&fh探索思路。。。&/b&
&div id=&i&&
&my-input&&/my-input&
ponent('my-input', {
render: function (createElement) {
if (this.items[0].name === 'world') {
return createElement('ol', this.items.map(function (item) {
return createElement('li', item.name)
return createElement('p', 'No items found.')
data: function () {
{name: 'world'},
{name: 'hello'}
{type: 'button',},
{type: 'checkbox'},
{type: 'color',name:'color'},
{type: 'date'},
{type: 'datetime'},
{type: 'datetime-local'},
{type: 'email '},
{type: 'file '},
{type: 'hidden'},
{type: 'image'},
{type: 'month'},
{type: 'number '},
{type: 'password '},
{type: 'radio'},
{type: 'range'},
{type: 'reset'},
{type: 'search'},
{type: 'submit'},
{type: 'tel'},
{type: 'text
{type: 'time
{type: 'url '},
{type: 'week '},
&b&v-model需要自己完善逻辑&/b&
&div id=&inputs&&
&inputs&&/inputs&
ponent('inputs', {
render: function (createElement) {
//保证this指向组件自身
var self =
return createElement('input', {
domProps: {
value: self.value
input: function (e) {
self.value = e.target.value
data: function () {
value: 'hello'
let inputs = new Vue({
el: 'inputs',
&b&Slots&/b&
//You can access static slot contents as Arrays of VNodes from this.$slots:
render: function (createElement) {
// &div&&slot&&/slot&&/div&
return createElement('div', this.$slots.default)
//And access scoped slots as functions that return VNodes from this.$scopedSlots:
render: function (createElement) {
&!--// &div&&slot :text=&msg&&&/slot&&/div&--&
return createElement('div', [
this.$scopedSlots.default({
text: this.msg
//To pass scoped slots to a child component using render functions, use the scopedSlots field in VNode data:
render (createElement) {
return createElement('div', [
createElement('child', {
// pass scopedSlots in the data object
&!--// in the form of { name: props =& VNode | Array&VNode& }--&
scopedSlots: {
default: function (props) {
return h('span', props.text)
&h4&JSX&/h4&
&mark& 将 h 作为 createElement 的别名是一个通用惯例,你会发现在 Vue 生态系统中,实际上必须用到 JSX,如果在作用域中 h 失去作用, 在应用中会触发报错。
import AnchoredHeading from './AnchoredHeading.vue'
el: '#demo',
render (h) {
&AnchoredHeading level={1}&
&span&Hello&/span& world!
&/AnchoredHeading&
&div id=&jsx&&
&jsx&&/jsx&
//要用到babel
&h4&函数化组件&/h4&
一个 函数化组件 就像这样:标记组件为 functional, 这意味它是无状态(没有 data),无实例(没有 this 上下文)。
&pre&&code&
ponent('my-component', {
functional: true,
// 为了弥补缺少的实例, 提供第二个参数作为上下文
render: function (createElement, context) {
// Props 可选
//组件需要的一切都是通过上下文传递:
props: 提供props 的对象
children: VNode 子节点的数组
slots: slots 对象
data: 传递给组件的 data 对象
parent: 对父组件的引用
&/code&&/pre&
&div id=&fl&&
&smart-list&&/smart-list&
ponent('smart-list', {
//以下两步的改写,context便可访问外部数据,
functional: true,
render: function (createElement, context) {
return createElement('ul',this.msg+': hello');
props: {//提供props对象
type: Array,
required: true
isOrdered: Boolean
data(){return {
msg:'hello'
children: [
//VNode子节点数组
//对父组件的引用
el: '#fl',
items: ['1', '2', '3']
&p&虚拟DOM&/p&
&div id=&vd&&&/div&
const vda = new Vue({
el: '#vd',
see: 'red',
msg: 'hello world'
render(h) {
return h('div', {style: {background: this.see}}, [
h('span', {}, [this.msg])
setTimeout(function () {
vda.see = 'green';
vda.msg = 'to see visual DOM '
&div class=&fh&&
&see msg=&hello&&&/see&
const see = ponent('see', {
render: h=&h('div', {
'class': {
foo: true,
bar: false
color: 'red',
fontSize: '14px'
domProps: {
innerHTML: 'baz',
value: self.value
click: this.test,
input: function (e) {
self.value = e.target.value
nativeOn: {
click: this.nativeClickHandler
directives: [
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
scopedSlots: {
default: props =& h('span', props.text)
slot: 'name-of-slot',
key: 'myKey',
ref: 'myRef'
}, this.$slots.default),
methods: {
test: function () {
alert('ok')
const fh = new Vue({
el: '.fh',
components: {}
相关标签:
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!
请登录后,发表评论
评论(Enter+Ctrl)
评论加载中...
评论加载中...
Copyright (C)
All Rights Reserved | 京ICP备 号-2}

我要回帖

更多关于 vue.js render函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信