Vue的render函数
父组件:App,子组件:Testapp.vue中Test.vue组件是使用template模板2.使用render函数当不使用template模板,直接使用render函数,实现了同样的效果。所以:实际上template 在Vue内部最终也会编译成render函数3.第一个参数1.动态创建标签第一个参数 标签/组件名也可以由父组件传来,也就是render函数实现了动态创建标签:App.vue中传来
1.template模板
父组件:App,子组件:Test
app.vue中
<template>
<div id="app">
<h1>这是app组件</h1>
<Test></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
Test.vue组件 是使用template模板
<template>
<div>
<h2>hello,我是Test组件</h2>
</div>
</template>
<script>
export default {
name: 'Test'
}
</script>
2.使用render函数
当不使用template模板,直接使用render函数,实现了同样的效果。
<script>
export default {
name: 'Test',
// createElement与下面一致
render(createElement){
// 传三个参数 标签/组件名、选项、子元素(直接文本元素、或者使用data定义的数据等)
return createElement('h2',{},'hello,我是Test组件')
}
}
</script>
所以:实际上template 在Vue内部最终也会编译成render函数
<template>
<div>
<h2>hello,我是Test组件</h2>
</div>
</template>
//编译成render函数:
// createElement与下面一致
render(createElement){
// 传三个参数 标签/组件名、选项、子元素(直接文本元素、使用data定义的数据)
return createElement('h2',{},'hello,我是Test组件')
}
3.第一个参数
1.动态创建标签
第一个参数 标签/组件名 也可以由父组件传来,
也就是render函数实现了动态创建标签:
App.vue中传来tag=“h5”
<template>
<div id="app">
<h1>这是app组件</h1>
<Test tag="h5"></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
在Test.vue中定义props,实现了渲染’hello,我是Test组件’ 为h5标签:
<script>
export default {
name: 'Test',
props: {
tag: String
},
render (createElement) {
return createElement(this.tag, {}, 'hello,我是Test组件')
}
}
</script>
2.第一个参数是组件
再建一个Demo.vue组件
<template>
<div>
我是Demo组件,接受到我的父组件Test传来的数据是:{{ message }}
</div>
</template>
<script>
export default {
name: 'Demo',
props: {
message: String
}
}
</script>
Test.vue
<script>
import Demo from './Demo.vue'
export default {
name: 'Test',
components: {
Demo
},
render (createElement) {
return createElement(
// 第一个参数
Demo,
// 第二个参数
{
props: {
message: 'hello message'
}
},
// 没有第三个参数
)
}
}
</script>
App.vue:
<template>
<div id="app">
<h1>这是app组件</h1>
<Test ></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
4.第二个参数
给test组件的添加了类名、click点击事件。
给标签添加样式
点击 ‘hello,我是Test组件’ 就会console.log打印。
Test.vue
<script>
export default {
name: 'Test',
render (createElement) {
return createElement(
// 第一个参数
'h2',
// 第二个参数
{
attrs:
{
class: 'test'
},
on: {
click: () => { console.log('打印') }
}
},
// 第三个参数
'hello,我是Test组件')
}
}
</script>
<style>
.test{
color: red;
}
</style>
App.vue:
<template>
<div id="app">
<h1>这是app组件</h1>
<Test ></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
5.第三个参数
Test.vue
使用data定义的数据
<script>
export default {
name: 'Test',
data () {
return {
msg: 'hello 我是test组件'
}
},
render (createElement) {
return createElement(
// 第一个参数
'h2',
// 第二个参数
{},
// 第三个参数
this.msg
)
}
}
</script>
App.vue
<template>
<div id="app">
<h1>这是app组件</h1>
<Test ></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
第三个参数为引用类型数组
Test.vue:
<script>
export default {
name: 'Test',
data () {
return {
people: ['何幸福', '关涛', '王庆来', '万善堂']
}
},
render (createElement) {
return createElement(
// 第一个参数
'ul',
// 第二个参数
{
attrs:{
class:'test'
}
},
// 第三个参数 使用data的数据
this.people.map((name) => {
return createElement(
// 第一个参数
'li',
// 第二个参数
{
attrs: {
class: 'people'
},
on: {
click: () => {
console.log('点击li啦')
}
}
},
`${name}`
)
})
)
}
}
</script>
<style>
.test{
list-style: none;
}
.people{
font-size:20px;
}
</style>
相当于使用template如下:
<template>
<ul class="test">
<li v-for="(item, index) in people" :key="index" class="people" >
{{ item }}
</li>
</ul>
</template>
<script>
export default {
data () {
return {
people: ['何幸福', '关涛', '王庆来', '万善堂']
}
}
}
</script>
<style>
.test {
list-style: none;
}
.people {
font-size: 20px;
}
</style>
App.vue:
<template>
<div id="app">
<h1>这是app组件</h1>
<Test ></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
6.render函数妙用
父组件App传递level的值,子组件Test根据level的值使用不同的h标签渲染内容
App.vue:
<template>
<div id="app">
<h1>这是app组件</h1>
<Test :level="1"></Test>
<Test :level="2"></Test>
<Test :level="3"></Test>
<Test :level="4"></Test>
<Test :level="5"></Test>
<Test :level="6"></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
Test.vue:
<template>
<div>
<h1 v-if="level === 1">h1标签:aaa</h1>
<h2 v-else-if="level===2">h2标签:bbb</h2>
<h3 v-else-if="level===3">h3标签:ccc</h3>
<h4 v-else-if="level===4">h4标签:ddd</h4>
<h5 v-else-if="level===5">h5标签:eee</h5>
<h6 v-else-if="level===6">h6标签:fff</h6>
</div>
</template>
<script>
export default {
name: 'Test',
props: {
level: Number
}
}
</script>
改造第一步:插槽
App.vue
<template>
<div id="app">
<h1>这是app组件</h1>
<Test :level="1">h1标签:aaa</Test>
<Test :level="2">h2标签:bbb</Test>
<Test :level="3">h3标签:ccc</Test>
<Test :level="4">h4标签:ddd</Test>
<Test :level="5">h5标签:eee</Test>
<Test :level="6">h6标签:fff</Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
components: {
Test
}
}
</script>
Test.vue:
<template>
<div>
<h1 v-if="level === 1"><slot></slot></h1>
<h2 v-else-if="level===2"><slot></slot></h2>
<h3 v-else-if="level===3"><slot></slot></h3>
<h4 v-else-if="level===4"><slot></slot></h4>
<h5 v-else-if="level===5"><slot></slot></h5>
<h6 v-else-if="level===6"><slot></slot></h6>
</div>
</template>
<script>
export default {
name: 'Test',
props: {
level: Number
}
}
</script>
改造第二步:render
Test组件使用render函数,动态创建标签
<script>
export default {
name: 'Test',
props: {
level: Number
},
render (createElement) {
return createElement(
// 第一个参数
'h' + this.level,
{},
this.$slots.default
)
}
}
</script>
可见这个Test.vue组件中仅使用script标签
可改造为Test.js文件
export default {
props: {
level: Number
},
render (createElement) {
return createElement(
'h' + this.level,
this.$slots.default
)
}
}
或者:
export default {
props: {
level: Number
},
render (createElement) {
// console.log(createElement);
const tag = 'h' + this.level;
return (
<tag>
{this.$slots.default}
</tag>
)
}
}
更多推荐
所有评论(0)