render函数之jsx应用
一、模板缺陷(模板的最大特点是扩展难度大,不易扩展。可能会造成逻辑冗余)
<level :type="1">哈哈</level>
<level :type="2">呵呵</level>
<level :type="3">嘿嘿</level>
Level组件需要对不同的type产生不同的标签
<template>
<h1 v-if="type==1">
<slot></slot>
</h1>
<h2 v-else-if="type==2">
<slot></slot>
</h2>
<h3 v-else-if="type==3">
<slot></slot>
</h3>
</template>
<script>
export default {
props:{
type:{
type:Number
}
}
}
</script>
二、函数式组件
函数式组件没有模板,只允许提供render函数
<script>
export default {
render(h){
return h('h'+this.type,{},this.$slots.default);
},
props:{
type:{
type:Number
}
}
}
</script>
三、JSX应用
使用jsx会让代码看起来更加简洁易于读取
<script>
export default {
render(h){
const tag = 'h' + this.type;
return <tag>{this.$slots.default}</tag>;
},
props:{
type:{
type:Number
}
}
}
</script>
四、render方法定制组件
编写list组件可以根据用户传入的数据自动循环列表
<List :data="data"></List>
<script>
import List from './components/List'
export default {
data(){
return {
data:["苹果","香蕉","橘子"]
};
},
components:{
List
}
}
</script>
<!-- List组件渲染列表 -->
<template>
<div class="list">
<div v-for="(item,index) in data" :key="index">
<li>{{item}}</li>
</div>
</div>
</template>
<script>
export default {
props:{
data:Array,
default:()=>[]
}
}
</script>
通过render方法来定制组件
1、在父组件中传入render方法
<List :data="data" :render="render"></List>
<script>
export default {
render(h,name){
return <span>{name}</span>
},
data(){
return{
data:['西瓜','草莓','桃子']
}
}
}
</script>
我们需要createElement方法,就会想到可以编写某个函数组件,
将createElement方法传递出来
2、子组件接受方法传递给函数组件
<template>
<div class="list">
<template v-for="(item,index) in data" :key="index">
<li v-if="!render">{{item}}</li>
<ListItem v-else :item="item" :render="render"></ListItem>
</template>
</div>
</template>
<script>
import ListItem form './ListItem'
export default {
conponents:{
ListItem
},
props:{
data:{
type:Array,
default:()=>[]
},
render:{
type:Function
}
}
}
</script>
3、函数式组件
//ListItem.vue调用最外层render方法,将createElement方法传递出来
export default {
render(h){
this.render(h,this.item)
},
props:{
item:{
type:Function
},
render:{
type:Function
}
}
}
五、scope-slot
//使用v-slot可将子组件内部绑定在slot插槽上的值传递到父组件上使用:(原理:在子组件内部编译调用,所以可以调用到。)
<List>
<template v-slot="{item,index}">
{{item}}
</template>
<List>
<div v-for="(item,index) in data" :key="index">
<slot :item="item" :index="index"></slot>
</div>