前言:之前學VUE對插槽只有一個模糊的存值概念,最近在封裝自定義組件時,再次學習一下。
通過slot插槽向組件內部指定位置傳遞內容,通過slot可以父子傳參,簡化了進行自定義組件的封裝和使用。
自己對插槽理解
就是一個站位HTML模板,用來攜帶內容,插入到合適的位置,由父組件來決定其顯示的內容,使得模塊具有更強的複用性。
單個slot (默認插槽 或 匿名插槽)
就是沒有名字的插槽,一個組件裏面只允許存在一個匿名插槽。
父組件內容
<div class="fa">
<h1>父組件</h1>
<child>
<p>父組件中寫的文本</p>
</child>
</div>
子組件內容
- 父組件如果要在子組件中插入內容,子組件中必須存在slot 標籤
<div class="child">
<h2>子組件</h2>
<slot>匿名插槽的默認內容</slot>
</div>
編譯結果如下:
- child組件slot裏的內容會替換成 p標籤裏面的內容,如果父組件沒有在子組件插入內容則會渲染slot裏面的默認內容。
<div class="fa">
<div class="child">
<h2>子組件</h2>
<p>父組件中寫的文本</p>
</div>
</div>
具名slot
slot 元素有一個name特性,可以爲slot命名,多個 slot 可以有不同的名字,用來渲染不同的內容。
父組件內容
<div class="fa">
<h1>父組件</h1>
<child>
<div class="son" slot="s1">
<span>111</span>
</div>
<div class="son" slot="s2">
<span>222</span>
</div>
<-- 以下是多餘的內容,將會自動填充到匿名插槽中-->
<div class="son">
<span>333</span>
</div>
</child>
</div>
子組件內容
<div class="child">
<h2>子組件</h2>
// s1插槽
<slot name="s1"></slot>
// s2插槽
<slot name="s2"></slot>
// 匿名插槽
<slot></slot>
</div>
編譯結果如下:
- 父組件插入在子組件中的內容如果沒有加入slot特性,則自動填充到子組件的匿名插槽中。
<div class="fa">
<h1>父組件</h1>
<div class="child">
<h2>子組件</h2>
<div class="son">
<span>111</span>
</div>
<div class="son">
<span>222</span>
</div>
<div class="son">
<span>333</span>
</div>
</div>
</div>
具名插槽的縮寫方式
- 以#號形式加上插槽名稱
<div class="fa">
<h1>父組件</h1>
<child>
<div class="son" #s1>
...
</div>
</child>
</div>
作用域插槽
在父組件中渲染子組件的內容,並且將子組件數據傳遞到插槽中
父組件內容
- 在向具名插槽提供內容的時候,可以在 template 元素上使用 v-slot 指令,並以 v-slot 的參數的形式提供其名稱
<div class="fa">
<h1>父組件</h1>
<child >
<template v-slot="props">
{{props.item}}
</template>
</child>
</div>
注意點1:在Vue 2.6+中,如果只存在默認插槽,可以用以上簡寫法 ,否則必須完整書寫: v-slot:default=“props”
注意點2:在Vue 2.6+ 引入了v-slot 指令,在接下來所有的 2.x 版本中 slot 和 slot-scope 還可以使用,但不會出現在 Vue 3.0 中,詳細的內容自己查閱官方文檔吧。
子組件內容
<template>
<div class="child">
<h2>子組件</h2>
<ul>
<li v-for="item of arr" >
<slot :item="item"></slot>
</li>
</ul>
</div>
<template/>
<scirpt>
data(){
return {
arr:[111, 222, 333]
}
}
<scirpt/>
編譯結果如下:
<div class="fa">
<h1>父組件</h1>
<div class="child">
<h2>子組件</h2>
<ul>
<li >111</li>
<li >222</li>
<li >333</li>
</ul>
</div>
</div>
動態插槽名
動態指令參數
從 Vue2.6 開始,新增了動態指令參數,利用 [ ],如下例子:
<img v-bind:[attributeName]="url" />
data(){
return {
attributeName : 'src'
}
}
以上代碼在模板中相當於:
還可以用於 v-on 綁定動態事件、a標籤 的連接等。
<img :src="url" />
動態插槽名的寫法:
<child>
<template v-slot:[slotName]>
...
</template>
</child>
注意點
- 默認插槽的縮寫語法不能和具名插槽混用,因爲它會導致作用域不明確:
- Vue 2.6+引入了插槽名,不建議在元素上寫名字 ,最好就在template寫,規範一下 。
<child >
<template v-slot:default="props">
{{props.item}}
</template>
<template v-slot:s1="props">
{{props.item}}
</template>
</child>
<-- ----------------------------------------兩種寫法,不可混用 -->
<child >
<template #default="props">
{{props.item}}
</template>
<template #s1="props">
{{props.item}}
</template>
</child>
結束語
利用好插槽,可以提高代碼複用性。現在瞭解的只是很淺的東西,覺得不會的東西是越來越多了,哎呀,加油啦~