插槽
更新:2.6.0 中,具名插槽和作用域插槽引入了一個新的統一的語法 (即 v-slot 指令)
廢棄:slot 和 slot-scope特性
插槽目的
個人理解:子組件提供插槽位置(相當於占位),父組件任意提供插槽內容(相當於如何使用這個位置)
插槽內容
官方:Vue 實現了一套內容分發的 API,將 <slot>元素作為承載分發內容的出口。
自己:子組件通過<slot></slot>實現插槽,
父組件通過<template></template>並結合v-slot向某個插槽提供內容
***父組件不提供插槽內容時,則使用插槽的后備內容【默認值】
編譯作用域
規則:父級模板里的所有內容都是在父級作用域中編譯的;
子模板里的所有內容都是在子作用域中編譯的。
后備內容
插槽的后備內容:指默認值
具名插槽
(1)總結:
1.父組件<template> 元素v-slot指令分發插槽內容,子組件<slot>元素定義插槽;
2.<slot>元素name 特性指定插槽名;
3.<slot>元素不帶name特性時,為默認插槽,默認name為default;
4.任何沒有被包裹在帶有 v-slot的 <template> 元素中的內容都會被視為默認插槽的內容;
5.默認插槽也可用 <template>元素包裹默認插槽內容;
6.若沒有默認插槽,找不到匹配的內容將會被拋棄
//父組件中: 為header插槽添加內容 <template v-slot:header> 我的博客 </template> //對應: //子組件中 定義header插槽 <slot name="header">默認頭部</slot>
默認slot分發插槽內容
<template v-slot:default>
<p>博客內容</p>
</template>
(2)詳細例子
//子組件s_slot.vue <template> <div class="container"> <header> <h1>Slot</h1> <slot name="header">默認頭部</slot> </header> //不帶name特性的插槽是默認插槽,默認插槽的name="default" <main> <slot></slot> </main> <footer> <slot name="footer">默認底部</slot> </footer> </div> </template> <style> footer ul{ display: flex; align-items: center; background:lightblue; } footer ul li{ flex: 1; text-align: center; list-style: none; height: 30px; line-height: 30px; } </style>
//父組件Slot.vue <template> <!-- 具名插槽的使用 --> <template v-slot:header> 我的博客 </template> <!--默認插槽的使用1,用template包裹--> <template v-slot:default> <p>博客內容</p> </template> 或者 <!--默認插槽的使用2,不用template包裹--> <!--<p>博客內容</p>--> <!--具名插槽的縮寫--> <template #footer> <ul> <li>首頁</li> <li>我的</li> </ul> </template> </template> <script> import sSlot from '@/components/s_slot'; export default { components:{ sSlot }, } </script>
效果如果:
作用域插槽
理解:1.父組件分發插槽內容時,可訪問子組件中的數據
2.父組件分發插槽內容時,父組件可向子組件傳遞數據(參數)
如何實現:
第一種:實現父組件分發插槽內容時,可訪問子組件中的數據
1.將子組件的數據A作為一個特性(屬性)綁定到<slot>元素上,綁定在<slot>元素的特性稱為“插槽prop”
2.在父級作用域中,v-slot帶一個值B定義插槽prop的名字
3.詳細例子 (為比較,父組件使用情況分2種,默認和訪問數據)
//子組件中 <template> <div class="container"> <aside> <!-- 綁定在 <slot> 元素上的特性被稱為插槽 prop --> <!-- 為了讓user在父級的插槽內容上可用,需將user綁定在slot元素上 --> <slot name="aside" :user="user"> 名字:{{user.name}} 電視劇:{{user.TV}} </slot> </aside> </div> </template> <script> export default { data:function(){ return{ user:{ 'name':'李冰冰', 'TV':'再生緣' } } } } </script>
//父組件中使用子組件,默認時 <template v-slot:aside></template>
結果:
//父組件中使用子組件,訪問子組件數據時 <!-- v-slot 定義【插槽 prop】 的名字 為star--> <template v-slot:aside="star"> 我喜歡{{star.user.name}} </template>
結果:
第二種:父組件分發插槽內容時,父組件可向子組件傳遞數據(參數)
就是普通的父子組件傳參
1.父組件將數據A綁定
2.子組件通過props接收
3.詳細例子 (為比較,父組件使用情況分2種,默認和傳值)
//子組件中 <template> <header> <h1>作用域插槽</h1> <slot name="header">{{header}}</slot> </header> <div> <slot name="footer">{{footer}}</slot> </div> </template> <script> export default { props:{ header:{ type:String, default:'這是默認頭部' }, footer:{ type:String, default:'這是默認底部' } }, } </script>
//父組件中:不傳值時 <template> <sSlotScope> <template v-slot:header></template> <template #footer></template> </sSlotScope> </template> <script> import sSlotScope from '@/components/s_slotScope'; export default { components:{ sSlotScope }, data:function(){ return{ } } } </script>
結果:
//父組件中:傳值 <template> <sSlotScope :header="header" :footer="footer"> <template v-slot:header></template> <template #footer></template> </sSlotScope> </template> <script> import sSlotScope from '@/components/s_slotScope'; export default { components:{ sSlotScope }, data:function(){ return{ header:'我的愛好', footer:'快樂每一天', } } } </script>
結果:
具名插槽的縮寫
1.v-slot 縮寫:把參數之前的所有內容 v-slot: 替換為字符 #
如:v-slot:header 縮寫為 #header
2.縮寫只在其有參數的時候才可用。若為變量時,使用縮寫的話,必須明確插槽名