参考 segmentfault.com/a/119000001…
更多详情查看官网:cn.vuejs.org/v2/guide/re…
父组件
<template>
<div>
<child :my-data="items" ></child>
</div>
</template>
<script>
import child from './child'
export default {
data () {
return {
items: [1, 2, 3, 4]
}
}
}
</script>
一. 基本用法
子组件 child.js
export default {
props: {
myData: Array
},
render: function (createElement) {
return createElement('h3', this.myData)
}
}
注: 第一个标签参数为必填项 类型可以为 {String | Object | Function}
// Object
return createElement({
template: '<div></div>'//组件选项对象
});
// Function
var func = function() {
return {template: '<div></div>'}
};
return createElement(func());
二. 添加样式、方法
export default {
props: {
myData: Array
},
render: function (createElement) {
return createElement('h3', {
'class': {
foo: true,
bar: false
},
style: {
color: 'red',
fontSize: '18px'
},
attrs: {
id: 'my-data'
},
on: {
click: this.handleClick
}
domProps: {
innerHTML: this.myData
}
})
},
methods: {
handleClick: function() {
console.log(' I am data! ');
}
}
}
或者也可以把内容放在外面
return createElement('h3', {
'class': {
foo: true
},
},this.myData)}
三.添加子元素
return createElement('div', [ // 由createElement函数构建而成的数组
createElement('h1', '主标'), // createElement函数返回VNode对象,VNodes必须唯一
createElement('h2', '副标')
])
// var childNode = createElement('h1', '标题');
// return createElement('div', [
// childNode, childNode //VNodes必须唯一,渲染失败
// ]);
// }
四. 数组循环输出
const items = [1,2,3,4]
return createElement('div',
items.map(item=> {
return createElement('h3', item)
})
)
在模板中使用的v-if/v-else
同理
render: function (createElement) {
const items = [1,2,3,4]
if (items.length) {
return createElement('ul', items.map((item)=> {
return createElement('li', item)
}))
} else {
return createElement('p', 'No items found.')
}
}
五. this.$slots用法
父组件
<template>
<div>
<child>
<h1 slot="header"><span>About Me</span></h1>
<p>Here is some page content</p>
<p slot="footer">Copyright 2016 Evan You</p>
<p>If I have some content down here</p>
</child>
</div>
</template>
<script>
import child from './child'
</script>
子组件 child.js
const {header, footer} = this.$slots
const body =this.$slots.default
return createElement('div', [
createElement('header', header),
createElement('main', body),
createElement('footer', footer)
])
六. v-model用法
父组件
<template>
<div>
<child :name="name" @input="val=>name=val"></child>
<div>你的名字是:{{name}}</div>
</div>
</template>
<script>
import child from './child'
export default {
data () {
return {
name: ''
}
}
}
</script>
子组件 child.js
export default {
props: {
name: String
},
render: function (createElement) {
return createElement('input', {
domProps: {
value: this.name
},
on: {
input: event=> {
self.$emit('input', event.target.value)
}
}
})
}
}
七.作用域插槽(获取子组件数据)
父组件
<template>
<child>
<template scope="props">
<span>{{props.text}}</span>
</template>
</child>
</template>
子组件 child.js
export default {
render: function (createElement) {
return createElement('div',
this.$scopedSlots.default({
text: 'hello world!'
})
)
},
}
八. 子组件之间传递作用域插槽
子组件 child.js
import Vue from 'vue'
export default {
render: function (createElement) {
return createElement('div', [
createElement('children', {
scopedSlots: {
default: function (props) {
return [
createElement('span', '来自父组件'),
createElement('span', props.text)
]
}
}
})
])
}
}
Vue.component('children', {
render: function (createElement) {
return createElement('b',
this.$scopedSlots.default({
text: '我是子组件'
}))
}
})
九. 函数化组件
父组件
<template>
<div>
<child :data="data"></child>
</div>
</template>
<script>
import child from './child'
export default {
data () {
return {
data: {
type:'',
content:''
}
}
},
components: {child},
methods: {
change: function(type) {
this.data.type=type
const content = () => {
switch (type) {
case 'img':
return 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png'
case 'video':
return 'http://vjs.zencdn.net/v/oceans.mp4'
default:
return '这是一段纯文本'
}
}
this.data.content=content()
}
},
mounted: function () {
this.change('img')
}
}
</script>
子组件 child.js
// 图片组件
var ImgItem = {
props: ['data'],
render: function (createElement) {
return createElement('div', [
createElement('p', '图片组件'),
createElement('img', {
attrs: {
src: this.data.content
}
})
])
}
}
// 视频组件
var VideoItem = {
props: ['data'],
render: function (createElement) {
return createElement('div', [
createElement('p', '视频组件'),
createElement('video', {
attrs: {
src: this.data.content,
controls: 'controls',
autoplay: 'autoplay'
}
})
])
}
}
// 纯文本组件
var TextItem = {
props: ['data'],
render: function (createElement) {
return createElement('div', [
createElement('p', '纯文本组件'),
createElement('p', this.data.content)
])
}
}
export default {
functional: true,
render: function (createElement, context) {
function getComponent () {
var data = context.props.data
switch (data.type) {
case 'img':
return ImgItem
case 'video':
return VideoItem
default:
return TextItem
}
}
return createElement(
getComponent(),
context.data
// context.children
)
}
//在 2.3.0 或以上的版本中,你可以省略 props选项,所有组件上的特性都会被自动解析为 props。
// props:{
// data:Object
//},
}
注: 在添加 functional: true 之后,锚点标题组件的 render 函数之间简单更新增加 context 参数,this.$slots.default 更新为 context.children,之后this.data 更新为 context.props.data
组件需要的一切都是通过上下文传递,包括:
- props:提供所有 prop 的对象
- children: VNode 子节点的数组
- slots: 返回所有插槽的对象的函数
- data:传递给组件的数据对象,作为 createElement 的第二个参数传入组件
- parent:对父组件的引用
- listeners: (2.3.0+) 一个包含了所有在父组件上注册的事件侦听器的对象。这只是一个指向 data.on 的别名。
- injections: (2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性。