vue的h函数_Vue中的render函数render: h => h(App)

在学习Vue.js时,使用vue-cli创建了一个Vue项目,main.js文件中有一行经典代码 render: h => h(App),那她是什么意思呢?

main.js 文件内容

import Vue from 'vue'

import App from './App.vue'

new Vue({

el: '#app',

render: h => h(App)

})

接下来就是答案喽

{

render: h => h(App);

}

等价于

{

render: h => {

return h(App);

}

}

等价于

{

render: function(h) {

return h(App);

}

}

即:

{

render: function(createElement) {

return createElement(App);

}

}

上一个示例

Document

var app = new Vue({

el: '#app', // 提供一个在页面上已经存在的 DOM 元素作为 Vue 实例挂载目标

render: function (createElement) {

return createElement('h2', 'Hello Vue!');

}

});

createElement 有这么几个重要的参数

第一个参数(必须) - {String | Object | Function}

render

Vue.component('elem', {

render: function(createElement) {

return createElement('div');//一个HTML标签字符

/*return createElement({

template: '

});*/

/*var func = function() {

return {template: '

};

return createElement(func());//一个返回HTML标签字符或组件选项对象的函数*/

}

});

new Vue({

el: '#app'

});

第二个参数(可选) - {Object}

render

Vue.component('elem', {

render: function(createElement) {

var self = this;

return createElement('div', {//一个包含模板相关属性的数据对象

'class': {

foo: true,

bar: false

},

style: {

color: 'red',

fontSize: '14px'

},

attrs: {

id: 'foo'

},

domProps: {

innerHTML: 'baz'

}

});

}

});

new Vue({

el: '#app'

});

第三个参数(可选) - {String | Array}

render

Vue.component('elem', {

render: function(createElement) {

var self = this;

// return createElement('div', '文本');//使用字符串生成文本节点

return createElement('div', [//由createElement函数构建而成的数组

createElement('h1', '主标'),//createElement函数返回VNode对象

createElement('h2', '副标')

]);

}

});

new Vue({

el: '#app'

});

两种组件写法对比

render

/*Vue.component('ele', {

template: '

文本
',

data: function() {

return {

show: true

}

},

methods: {

handleClick: function() {

console.log('clicked!');

}

}

});*/

Vue.component('ele', {

render: function(createElement) {

return createElement('div', {

'class': {

show: this.show

},

attrs: {

id: 'elem'

},

on: {

click: this.handleClick

}

}, '文本');

},

data: function() {

return {

show: true

}

},

methods: {

handleClick: function() {

console.log('clicked!');

}

}

});

new Vue({

el: '#app'

});

this.$slots用法

render

About Me

Here's some page content

Copyright 2016 Evan You

If I have some content down here

Vue.component('blog-post', {

render: function(createElement) {

var header = this.$slots.header,//返回由VNode组成的数组

body = this.$slots.default,

footer = this.$slots.footer;

return createElement('div', [

createElement('header', header),

createElement('main', body),

createElement('footer', footer)

])

}

});

new Vue({

el: '#app'

});

使用props传递数据

render

Vue.component('ele', {

render: function(createElement) {

if (this.show) {

return createElement('p', 'true');

} else {

return createElement('p', 'false');

}

},

props: {

show: {

type: Boolean,

default: false

}

}

});

new Vue({

el: '#app',

data: {

show: false

}

});

VNodes必须唯一

render

var child = {

render: function(createElement) {

return createElement('p', 'text');

}

};

/*Vue.component('ele', {

render: function(createElement) {

var childNode = createElement(child);

return createElement('div', [

childNode, childNode//VNodes必须唯一,渲染失败

]);

}

});*/

Vue.component('ele', {

render: function(createElement) {

return createElement('div',

Array.apply(null, {

length: 2

}).map(function() {

return createElement(child)//正确写法

})

);

}

});

new Vue({

el: '#app'

})

v-model指令

render

name=val">

你的名字是{{name}}

Vue.component('el-input', {

render: function(createElement) {

var self = this;

return createElement('input', {

domProps: {

value: self.name

},

on: {

input: function(event) {

self.$emit('input', event.target.value);

}

}

})

},

props: {

name: String

}

});

new Vue({

el: '#app',

data: {

name: 'hdl'

}

});

作用域插槽

render

{{props.text}}

Vue.component('ele', {

render: function(createElement) {

// 相当于

return createElement('div', [

this.$scopedSlots.default({

text: this.msg

})

]);

},

data: function() {

return {

msg: '来自子组件'

}

}

});

new Vue({

el: '#app'

});

向子组件中传递作用域插槽

render

Vue.component('ele', {

render: function(createElement) {

return createElement('div', [

createElement('child', {

scopedSlots: {

default: function(props) {

return [

createElement('span', '来自父组件'),

createElement('span', props.text)

];

}

}

})

]);

}

});

Vue.component('child', {

render: function(createElement) {

return createElement('b', this.$scopedSlots.default({text: '我是组件'}));

}

});

new Vue({

el: '#app'

});

函数化组件

render

切换为图片为组件

切换为视频为组件

切换为文本组件

// 图片组件选项

var ImgItem = {

props: ['data'],

render: function(createElement) {

return createElement('div', [

createElement('p', '图片组件'),

createElement('img', {

attrs: {

src: this.data.url

}

})

]);

}

}

// 视频组件

var VideoItem = {

props: ['data'],

render: function(createElement) {

return createElement('div', [

createElement('p', '视频组件'),

createElement('video', {

attrs: {

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)

]);

}

};

Vue.component('smart-item', {

functional: true,

render: function(createElement, context) {

function getComponent() {

var data = context.props.data;

if (data.type === 'img') return ImgItem;

if (data.type === 'video') return VideoItem;

return TextItem;

}

return createElement(

getComponent(),

{

props: {

data: context.props.data

}

},

context.children

)

},

props: {

data: {

type: Object,

required: true

}

}

});

new Vue({

el: '#app',

data() {

return {

data: {}

}

},

methods: {

change: function(type) {

if (type === 'img') {

this.data = {

type: 'img',

url: 'https://raw.githubusercontent.com/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');

}

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值