前言
slot插值官方网站的介绍是一笔带过,有很多想使用的看到这个情况,就会放弃,但是这个着实是一个非常好用的功能
功能介绍
- 匿名插槽
//Child.vue
<template>
<div>
<slot>我是子组件</slot>
</div>
</template>
//Parent.vue
<template>
<div>
<Child>
被父组件引用
</Child>
</div>
</template>
效果图
image.png- 具名插槽
//Child.vue
<template>
<div>
<slot name="first">我是子组件第一行</slot>
<slot name="second">我是子组件第二行</slot>
<slot name="third">我是子组件第三行</slot>
</div>
</template>
//Parent.vue
<template>
<div>
<Child>
<div slot="first">被父组件修改的第一行</div>
<div slot="second">被父组件修改的第二行</div>
</Child>
</div>
</template>
//效果图
image.png
这上面的两种用法 大部分人应该都用过了,其实就是子组件留一个插槽,如果父组件有定制化的内容直接修改就可以达成目的
- 有值插槽(作用域插槽)
就是子组件插槽上带的有值(这个值可以是子组件自己的,也可以是父组件传给子组件的),并把这些值暴露给父组件
第一种用法
//Child.vue
<template>
<div class="child-style">
<slot :data="testData">我是子组件第一行</slot>
</div>
</template>
testData: ['apple','banana','orange']
//Parent.vue
<template>
<div>
<Child>
<template slot-scope="fruits">
{{fruits.data}}
</template>
</Child>
</div>
</template>
//效果图
image.png
第二种用法
//Child.vue
<template>
<div class="child-style">
<slot :data="testData">我是子组件第一行</slot>
</div>
</template>
//Parent.vue
<template>
<div>
<Child>
<template slot-scope="fruits">
<div v-for="item in fruits.data" :key="item">{{item}}</div>
</template>
</Child>
</div>
</template>
//效果图
image.png
第三种用法
//Child.vue
<template>
<div class="child-style">
<slot name="first" :data="fruiltData">我是子组件第一行</slot>
<slot name="second" :data="animalData">我是子组件第二行</slot>
</div>
</template>
//Parent.vue
<template>
<div>
<Child>
<template slot="first" scope="firstData">
<div v-for="item in firstData.data" :key="item"> {{item}}</div>
</template>
<template slot="second" scope="secondData">
<div v-for="list in secondData.data" :key="list"> {{list}}</div>
</template>
</Child>
</div>
</template>
//效果图
image.png
使用场景举例
- 第一个场景
子组件定义大部分功能,父组件自身完成定制(仅属于自己)的功能
流程
父组件动态请求值给子组件
子组件绑定数据然后把接口和数据在暴露给父组件
//Child.vue
<template>
<div class="child-style">
<slot name="first" :data="testData">我是子组件第一行</slot>
</div>
</template>
<script>
export default {
name: 'Child',
props: {
testData: Array
},
data(){
return{
}
}
}
</script>
<style lang="scss" scoped>
.child-style{
div{
background: #00c585;
color: #fff;
line-height: 30px;
}
}
</style>
//Parent.vue
<template>
<div>
<Child :testData="row">
<template slot="first" scope="arrayList">
<div v-for="item in arrayList.data" :key="item">{{item }}</div>
</template>
</Child>
</div>
</template>
<script>
import Child from './Child';
export default {
name: 'parent',
data(){
return{
row:["apple",'banana','orange']
}
},
components:{
Child
}
}
</script>
//效果图
image.png
可能有些人不太理解为什么 我不直接在子组件里动态请求数据,然后处理好所有的逻辑,父组件直接调用,其实这种一种很理想的做法,但是大多数开发的时候是不会这么理想的
举个例子来说,我有一个子组件Child.vue,被ParentA.vue引用,过一段时间ParentB.vue也需要用到Child.vue但是只能用到里面的80%,另外20%是与Child.vue不一样的,怎么办,难道我要copy Child.vue随便改吧改吧???
当然也行,但是是不是感觉很low,对你自己也没有长进,这个时候比较好的做法就是把其中公用的80%,提取出来,然后可定制的20%,通过作用域插槽(有值插槽)让父组件来处理,这个时候就比较完美了
- 第二个场景
看上图我有三个组件A,B,C。C组件又分为组件的上半部分和下半部分
如果这个时候我们要让组件A和组件C(上)换位置怎么半???
难道需要重新把组件A复制到C(上),把C(上)复制到A???
如果你的C组件上半部分与C组件下半部分交互比较少,还ok,如果交互复杂的话,这样做估计又要掉一把头发了
这个时候我们就可以使用组件分发来做了
//Child.vue
<template>
<div >
<div >
<ul class="child-style">
<li v-for="fruilt in fruiltsData" :key="fruilt">{{fruilt}}</li>
</ul>
<slot name="slot-firstchild"></slot>
<slot name="slot-secondchild"></slot>
<ul class="child-style">
<li v-for="animal in animalsData" :key="animal">{{animal}}</li>
</ul>
</div>
</div>
</template>
fruiltsData: ['apple','banana','orange'],
animalsData: ['dog','cat','pig']
//Parent.vue
<template>
<div>
<Child1>
<Child3 slot="slot-firstchild"></Child3>
<Child2 slot="slot-secondchild"></Child2>
</Child1>
</div>
</template>
//效果图
image.png
除了列举的两个场景,solt还有不少别的用法,由于篇幅的原因,下次再讲把。。。
网友评论