一. 簡介及基本用法
1. 簡介
(1). 什么時候使用插槽?
插槽的使用過程其實是抽取共性、預留不同;
我們會將共同的元素、內容依然在組件內進行封裝;
同時會將不同的元素使用slot作為占位,讓外部決定到底顯示什么樣的元素;
(2). 如何定義插槽?
在封裝組件中,使用特殊的元素<slot>就可以為封裝組件開啟一個插槽;
該插槽插入什么內容取決於父組件如何使用;
2. 基本使用 (匿名插槽)
(1). 基本用法
(2). 插槽默認內容
有時候我們希望在使用插槽時,如果沒有插入對應的內容,那么我們需要顯示一個默認的內容:當然這個默認的內容只會在沒有提供插入的內容時,才會顯示。
子組件
<template> <div> <h4>-------------我是MySlot1開始部分------------</h4> <slot> <h6 class="h6">我是插槽默認的內容哦,如果不填充,就顯示我</h6> </slot> <h4>-------------我是MySlot1結束部分------------</h4> </div> </template>
父組件
<template> <div> <my-slot1> <!-- <h4>我是填充內容1</h4> <a href="#">我是填充內容2</a> <h4>我是填充內容3</h4> --> </my-slot1> </div> </template>
二. 具名插槽
1. 背景
我們希望達到一個插槽對應一塊內容的顯示,這個時候我們就可以使用 具名插槽。
2. 基本用法
具名插槽顧名思義就是給插槽起一個名字,<slot> 元素有一個特殊的 attribute:name屬性;一個不帶 name 的slot,會帶有隱含的名字 default;
父組件在調用的時候,可以使用 v-slot 綁定名稱從而實現對應,v-slot也可以縮寫為 #。
子組件
<template> <div class="nav-bar"> <!-- <slot name="default"></slot> --> <div class="left"> <slot name="left1"></slot> </div> <div class="center"> <slot name="center1"></slot> </div> <div class="right"> <slot name="right1"></slot> </div> </div> </template>
父組件
<template> <div> <my-slot-cpn1> <template v-slot:left1> <button>左邊按鈕</button> </template> <template #center1> <button>我是中間按鈕</button> </template> <template #right1> <button>右邊按鈕</button> </template> </my-slot-cpn1> </div> </template>
3. 動態插槽名
可以通過 v-slot:[dynamicSlotName]方式動態綁定一個名稱。
子組件
<template> <div class="nav-bar"> <div class="addition"> <slot :name="name"></slot> </div> </div> </template> <script> export default { data() { return { name:'ypf' }; } } </script>
父組件
<template> <div> <my-slot-cpn1> <template #[name]> <button>ypf內容</button> </template> </my-slot-cpn1> </div> </template> <script> import MySlotCpn1 from './MySlotCpn1.vue'; export default { components: { MySlotCpn1 }, data() { return { name:'ypf' }; } } </script>
三. 作用域插槽
1. 背景
我們希望父組件中 插槽位置 可以訪問到子組件中的內容。默認情況下,如下圖,是無法訪問的。
2. 如何解決?
(1). 插槽 prop (子組件)
通過綁定在 <slot>
元素上的 attribute 向外傳遞,這個attribute被稱為插槽 prop。
<template> <div> <template v-for="(item,index) in myList" :key="index"> <slot :item="item" :index="index">{{index}}</slot> </template> </div> </template> <script> export default { props: { myList: { type: Array, default: () => [] } }, data() { return {}; } } </script>
(2). 父組件中,可以使用帶值的 v-slot
來定義我們提供的插槽 prop 的名字,從而獲取插糟中的屬性。
代碼分享:省略部分不關鍵代碼
<template> <div> <!-- 2. 作用域插槽--> <!-- 2.1 通過v-slot:default聲明調用 --> <show-names2 :myList="myList"> <template v-slot:default="myInfo"> <button>{{myInfo.item}}----{{myInfo.index}}</button> </template> </show-names2> <!-- 2.2 獨占默認插槽的縮寫語法 省略template --> <show-names2 :myList="myList"> <template v-slot="myInfo"> <button>{{myInfo.item}}----{{myInfo.index}}</button> </template> </show-names2> <!-- 2.3 可以直接加在組件上 --> <show-names2 :myList="myList" v-slot="myInfo"> <button>{{myInfo.item}}----{{myInfo.index}}</button> </show-names2> </div> </template> <script> export default { data() { return { myList: ["ypf1", "ypf2", "ypf3", "ypf4"], }; } } </script>
3. 獨占默認插槽縮寫
(1). 如果我們的插槽是默認插槽default,那么在使用的時候 v-slot:default="myInfo"可以簡寫為v-slot="myInfo":
(2). 並且如果我們的插槽只有默認插槽時,組件的標簽可以被當做插槽的模板來使用,這樣,我們就可以將 v-slot 直接用在組件上:
<template> <div> <!-- 2. 作用域插槽--> <!-- 2.2 獨占默認插槽的縮寫語法 省略template --> <show-names2 :myList="myList"> <template v-slot="myInfo"> <button>{{myInfo.item}}----{{myInfo.index}}</button> </template> </show-names2> <!-- 2.3 可以直接加在組件上 --> <show-names2 :myList="myList" v-slot="myInfo"> <button>{{myInfo.item}}----{{myInfo.index}}</button> </show-names2> </div> </template> <script> export default { data() { return { myList: ["ypf1", "ypf2", "ypf3", "ypf4"], }; } } </script>
4. 默認插槽和具名插槽混合
如果我們有默認插槽和具名插槽,那么按照完整的template來編寫。
子組件:
<template> <div> <template v-for="(item,index) in myList" :key="index"> <!-- 插槽prop --> <slot :item="item" :index="index">{{index}}</slot> <!-- 具名插糟 --> <slot name="ypf"></slot> </template> </div> </template>
父組件:
<!-- 3. 多個插槽需要使用完整的template--> <show-names3 :myList="myList"> <template v-slot="myInfo"> <button>{{myInfo.item}}-{{myInfo.index}}</button> </template> <!-- 具名插糟 --> <template v-slot:ypf> <h2>我是ypf的插入內容</h2> </template> </show-names3>
!
- 作 者 : Yaopengfei(姚鵬飛)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
- 聲 明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。