「後端小夥伴來學前端了」Vue中 Slot 插槽的使用,同樣也可以實現父子元件之間通訊
前言
插槽可以說是 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="http://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="http://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="http://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="http://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>
後語
大家一起加油!!!如若文章中有不足之處,請大家及時指出,在此鄭重感謝。
紙上得來終覺淺,絕知此事要躬行。
大家好,我是博主
寧在春
:主頁一名喜歡文藝卻踏上程式設計這條道路的小青年。
希望:
我們,待別日相見時,都已有所成
。
- 「後端小夥伴來學前端了」Vue中 Slot 插槽的使用,同樣也可以實現父子元件之間通訊
- 「後端小夥伴來學前端了」為什麼Vue在有了全域性事件匯流排後還要引入Vuex呢?
- 「後端小夥伴來學前端了」Vue中利用全域性事件匯流排實現元件之間通訊
- Mysql 邏輯架構介紹
- Dockerfile中的保留字指令講解
- 針對 SpringSecurity 鑑權流程做了一個詳細分析,讓你明白它是如何執行的!
- UML圖 | 時序圖(順序、序列圖)繪製
- 通過簡單例子 | 快速理清 UML 中類與類的六大關係
- SpringBoot 整合 Thymeleaf & 如何使用後臺模板快速搭建專案
- Netty | 工作流程圖分析 & 核心元件說明 & 程式碼案例實踐
- 通過簡單例子 | 快速理清 UML 中類與類的六大關係
- JSON Web Token(縮寫 JWT) 目前最流行、最常見的跨域認證解決方案
- SpringBoot 對映路徑中 匹配正則表示式
- 通過生活案例快速 Get 執行緒池七個引數和工作原理
- SpringBoot實現固定、動態定時任務 | 三種實現方式