共计 6015 个字符,预计需要花费 16 分钟才能阅读完成。
前言
插槽能够说是 Vue 中十分重要的一部分吧,在我学习和练习的过程中,当组件搭配着插槽一起应用的时候,会施展的更好一些。更多时候也会更加不便。
明天介绍 Vue 中三种插槽吧:默认插槽、具名插槽、作用域插槽。
环境筹备
先搭个初始环境给大家看看哈。一步一步讲完这个插槽。
就是写了一个类别组件,别离渲染这三种数据。
Category 组件
<template> | |
<div class="category"> | |
<h1>{{title}}</h1> | |
<ul> | |
<li | |
v-for="(item,index) in listData" | |
:key="index">{{item}}</li> | |
</ul> | |
</div> | |
</template> | |
<script> | |
export default { | |
props: { | |
listData:Array, | |
title: String | |
} | |
} | |
</script> | |
<style scoped> | |
.category{ | |
width: 200px; | |
height: 300px; | |
background-color:pink; | |
} | |
</style> |
App 组件
<template> | |
<div id="app"> | |
<Category :listData="games" :title="'Games'" /> | |
<Category :listData="movies" :title="'Movies'" /> | |
<Category :listData="foods" :title="'Foods'" /> | |
</div> | |
</template> | |
<script> | |
import Category from './components/Category.vue' | |
export default { | |
name: 'App', | |
components: {Category}, | |
data () { | |
return {games:['穿梭前线','qq 飞车','洛克王国'], | |
movies:['你好,李焕英','青春派','匆匆那年'], | |
foods:['邵阳米粉','长沙茶颜','重庆火锅'] | |
} | |
} | |
} | |
</script> | |
<style> | |
#app { | |
font-family: Avenir, Helvetica, Arial, sans-serif; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
text-align: center; | |
color: #2c3e50; | |
margin-top: 60px; | |
display: flex; | |
justify-content: space-between; | |
} | |
</style> |
最开始就是如上图一样的需要,然而当初业务需要更改了,电影变成了只宣传其中一个,其余的不进行宣传,吃的也变成只宣传一个拉。
如下图:
咱们怎么改适合呢?
是在 Category
组件中加 if
一个个进行判断吗?还是有更好的办法勒???
一个个判断是不行的,那样子代码会变得非常繁冗,不易浏览,万一当前又要更改业务需要,代码都不好动。
接下来就到默认插槽的呈现拉。
一、默认插槽
咱们在子组件中不必再用props
接收数据,也不做渲染,而是定义一个插槽。
<template> | |
<div class="category"> | |
<!-- 定义插槽,插槽默认内容 --> | |
<slot> 如果当父组件不传值过去,即显示此默认 </slot> | |
</div> | |
</template> | |
<script> | |
export default {props: {} | |
} | |
</script> |
App 组件也作出更改
<template> | |
<div id="app"> | |
<Category> | |
<h1>Games</h1> | |
<!-- <ul> | |
<li v-for="(item, index) in games" :key="index">{{item}}</li> | |
</ul> --> | |
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e"> | |
</Category> | |
<Category> | |
<h1>Movies</h1> | |
<img class="movies" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f"> | |
<!-- <ul> --> | |
<!-- <li v-for="(item, index) in movies" :key="index">{{item}}</li> --> | |
<!-- </ul> --> | |
</Category> | |
<Category> | |
<h1>Foods</h1> | |
<ul> | |
<li v-for="(item, index) in foods" :key="index">{{item}}</li> | |
</ul> | |
</Category> | |
<!-- 当咱们什么都没有写的时候,看展现什么 --> | |
<Category> | |
</Category> | |
</div> | |
</template> | |
<script> | |
import Category from './components/Category.vue' | |
export default { | |
name: 'App', | |
components: {Category}, | |
data () { | |
return {games:['穿梭前线','qq 飞车','洛克王国'], | |
movies:['你好,李焕英','青春派','匆匆那年'], | |
foods:['邵阳米粉','长沙茶颜','重庆火锅'] | |
} | |
} | |
} | |
</script> |
显示成果:
解释:
咱们在子组件写了一个<slot> 如果当父组件不传值过去,即显示此默认 </slot>
标签,此处就相当于占了一个地位。
咱们在父组件中,也不再像之前一样 <Category/>
写自闭和标签,而是写了非自闭和标签<Category> 内容 </Category>
。这样做,Vue 就会默认的将写在组件标签中的内容渲染完,而后再放回子组件中的 <slot></slot>
占好地位的中央去。
留神
:CSS 款式写在父组件或者子组件中都是能够的,因为它是渲染完后才放回子组件中的。写在子组件中,就是在放回子组件中时渲染。
写完这里,客户忽然感觉你们这么厉害,不满足啦,又开始给你们整幺蛾子。
接下来就又到具名插槽退场啦哈。
二、具名插槽
居然咱们可能想到用一个插槽啦,那么为什么不能想着用两个插槽来试一试勒?
革新子组件
<template> | |
<div class="category"> | |
<!-- 必须加上名称 在父组件中能力指定要放入那个插槽 这也是为什么叫做具名插槽的起因 ---> | |
<slot name="slot1"> 如果当父组件不传值过去,即显示此默认 </slot> | |
<slot name="slot2"></slot> | |
</div> | |
</template> | |
<script> | |
export default {props: {} | |
} | |
</script> |
父组件
<template> | |
<div id="app"> | |
<Category> | |
<template slot="slot1"> | |
<h1>Games</h1> | |
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e" | |
/> | |
</template> | |
<template slot="slot2"> | |
<button > qq 登录 </button> | |
<button > 微信登录 </button> | |
</template> | |
</Category> | |
<Category> | |
<template slot="slot1"> | |
<h1>Movies</h1> | |
<img | |
class="movies" | |
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f" | |
/> | |
</template> | |
<template slot="slot2"> | |
<button > 点击购票 </button> | |
</template> | |
</Category> | |
<Category> | |
<template slot="slot1"> | |
<h1>Foods</h1> | |
<ul> | |
<li v-for="(item, index) in foods" :key="index">{{item}}</li> | |
</ul> | |
</template> | |
</Category> | |
<!-- 当咱们什么都没有写的时候,看展现什么 --> | |
<Category> </Category> | |
</div> | |
</template> | |
<script> | |
import Category from './components/Category.vue' | |
export default { | |
name: 'App', | |
components: {Category}, | |
data () { | |
return {games:['穿梭前线','qq 飞车','洛克王国'], | |
movies:['你好,李焕英','青春派','匆匆那年'], | |
foods:['邵阳米粉','长沙茶颜','重庆火锅'] | |
} | |
} | |
} | |
</script> |
成果展现
解释:
咱们能够在组件中放多个 slot,然而多个的时候必须要给他们命名,另外父组件中也要进行指定,这样才不会放不进去。
三、作用域插槽
作用域插槽和后面稍稍有点不同,之前都是数据在父组件中,而作用域插槽是数据在子组件中,反过来传递给父组件,让父组件定义构造进行渲染。
革新的子组件
<template> | |
<div class="category"> | |
<slot name="slot1"> 如果当父组件不传值过去,即显示此默认 </slot> | |
<slot name="slot2" :foods="foods"> 如果当父组件不传值过去,即显示此默认 </slot> | |
</div> | |
</template> | |
<script> | |
export default {data () { | |
return{foods:['邵阳米粉','长沙茶颜','重庆火锅'] | |
} | |
} | |
} | |
</script> |
父组件
<template> | |
<div id="app"> | |
<Category> | |
<template slot="slot1"> | |
<h1>Foods</h1> | |
</template> | |
<template slot="slot2" scope="listData"> | |
<!-- 如果不晓得的 咱们能够输入看看这是什么· {{listData}} --> | |
<ul> | |
<li v-for="(item, index) in listData.foods" :key="index"> | |
{{item}} | |
</li> | |
</ul> | |
</template> | |
</Category> | |
<Category> | |
<template slot="slot1"> | |
<h1>Foods</h1> | |
</template> | |
<template slot="slot2" scope="listData"> | |
<ol> | |
<li v-for="(item, index) in listData.foods" :key="index"> | |
{{item}} | |
</li> | |
</ol> | |
</template> | |
</Category> | |
<Category> | |
<template slot="slot1"> | |
<h1>Foods</h1> | |
</template> | |
<template slot="slot2" scope="listData"> | |
<h4 v-for="(item, index) in listData.foods" :key="index"> | |
{{item}} | |
</h4> | |
</template> | |
</Category> | |
<Category> | |
<template slot="slot1" scope="listData"> | |
{{listData}} | |
</template> | |
</Category> | |
</div> | |
</template> | |
<script> | |
import Category from './components/Category.vue' | |
export default { | |
name: 'App', | |
components: {Category} | |
} | |
</script> |
效果图
这种我在学习及练习过程中,并没有想到哪些应用场景,然而在官网上有案例,我想它必然是有存在的理由,只是我的见识太少,而未能利用到而已。
解释:
子组件中通过: 变量名 ="定义的数据"
向父组件传值,父组件用 <template slot="slot2" scope="不必和子组件传递过去的名称雷同">
接管,因为还要. 一层,才到
<template slot="slot2" scope="listData"> | |
<!-- 如果不晓得的 咱们能够输入看看这是什么· {{listData}} --> | |
<ul> | |
<li v-for="(item, index) in listData.foods" :key="index"> | |
{{item}} | |
</li> | |
</ul> | |
</template> |
后语
大家一起加油!!!如若文章中有不足之处,请大家及时指出,在此郑重感激。
纸上得来终觉浅,绝知此事要躬行。
大家好,我是博主
宁在春
:主页一名喜爱文艺却踏上编程这条路线的小青年。
心愿:
咱们,待别日相见时,都已有所成
。