本文所讲的都是在自定义组件中使用render函数的栗子,更多内容请查看官网或者(https://segmentfault.com/a/1190000010913794?utm_source=tag-newest)
首先在根组件引用实例组件(使用vue-cl3的vue serve 启动服务,点击详情)
1. 简单的渲染一个元素
<script>
export default {
render: function(createElement) {
return createElement(
'div', {
class: {
child: true,
more: false
},
attrs: {
id: 'foo',
name: 'child'
},
style: {
width: '100%',
height: '50px'
},
domProps: {
innerHTML: 'child-innerHTML'
}
},
)
}
}
</script>
<style scoped>
.child {
background: pink
}
.more {
background: red
}
</style>
2. 添加子标签
<script>
export default {
render: function(createElement) {
return createElement(
'div', {
class: 'child',
style: {
width: '100%'
},
}, [
createElement('h1', '标题'),
createElement('h2', {
attrs: {
id: 'child-h2'
},
class: 'more',
style: {
width: '100%',
height: '50px'
},
domProps: {
innerHTML: 'h2'
}
}),
]
)
}
}
</script>
<style scoped>
.child {
background: pink
}
.more {
background: red
}
</style>
3. this.$slots的用法
// 根组件
<template>
<div>
<child>
<h1 slot="childheader">childheader</h1>
<h2 slot="childbody">childbody</h2>
<h3 slot="childfooter">childfooter</h3>
</child>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: {
child
}
}
</script>
// 子组件
<script>
export default {
render: function(createElement) {
let childheader = this.$slots.childheader,
childbody = this.$slots.childbody,
childfooter = this.$slots.childfooter;
return createElement(
'div', {
class: 'child',
style: {
width: '100%'
},
}, [
createElement('div', childheader),
createElement('div', childbody),
createElement('div', childfooter),
]
)
}
}
</script>
<style scoped>
.child {
background: pink
}
.more {
background: red
}
</style>
4. v-model
首先需要知道的是,render函数并没有与v-model对应,你必须自己实现逻辑,这就是深入底层的代价,但是和v-model相比,这可以让你更好的控制交互细节
<script>
export default {
render: function(createElement) {
let self = this
return createElement(
'div', [
createElement('div', self.childinput),
createElement('input', {
domProps: {
value: self.childinput
},
on: {
input: function (event) {
self.childinput = event.target.value
}
}
})
]
)
},
data() {
return {
childinput: 'childinput'
}
},
watch: {
childinput(v) {
console.log(v)
}
}
}
</script>
<style scoped>
.child {
background: pink
}
.more {
background: red
}
</style>
5. 作用域插槽
这里需要使用的是this.$scopedSlots
// 跟组件
<template>
<div>
<child>
<template slot-scope="scoped">
{{scoped.text}}
</template>
</child>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: {
child,
}
}
</script>
// 子组件
<script>
export default {
render: function(createElement) {
let self = this
return createElement(
'div', {
style: {
width: '100%',
height: '50px'
},
class: 'child'
}, [
self.$scopedSlots.default({
text: this.childmsg
})
]
)
},
data() {
return {
childmsg: 'childmsg'
}
}
}
</script>
<style scoped>
.child {
background: pink
}
.more {
background: red
}
</style>