vue中的插槽(slot)
- 2020 年 3 月 10 日
- 筆記
vue中的插槽,指的是子組件中提供給父組件使用的一個佔位符,用<slot></slot>標籤表示,父組件可以在這個佔位符中填充任何模板程式碼,比如HTML、組件等,填充的內容會替換掉子組件的<slot></slot>標籤(替換佔位符)。
vue中的插槽大致可以分為默認插槽、具名插槽和作用域插槽三種。
默認插槽
默認插槽是最簡單的一種插槽,和上面的描述一致,就是通過替換佔位符達到在父組件中更改子組件中內容的效果。
在子組件中放置一個佔位符(插槽):
<template> <span> <span>誰是最可愛的人?</span> <slot></slot> </span> </template> <script> export default { name: 'child' } </script>
然後在父組件中引用這個子組件,並給這個佔位符(插槽)填充內容:
<template> <div> <span>今日問答:</span> <child> <span>當然是yanggb了</span> </child> </div> </template>
這個時候頁面展現的內容就會是【今日問答:誰是最可愛的人?當然是yanggb了】。
在上面的例子中,如果在子組件中沒有放置<slot><slot>標籤佔位符,就不會有【當然是yanggb了】這個答案了,問題永遠得不到任何回應,這就是插槽因此而存在的意義。事實上,如果子組件中沒有使用插槽,父組件要是需要往子組件中填充模板或者html,基本上是沒有其他辦法能做到的。
具名插槽
來想像一個這樣的場景:在子組件中有兩個要替換佔位符的地方(兩個插槽),這時候父組件如果要將相應的內容填充到相應的插槽中,靠默認插槽是沒有辦法的,因為沒有辦法判斷相應的內容要填充到哪個插槽中。為了應對這樣的場景,具名插槽應運而生。
所謂的具名插槽,其實就是給子組件中的插槽取一個名字,而父組件就可以在引用子組件的時候,根據這個名字對號入座,將相應內容填充到相應的插槽中。
在子組件中放置兩個具名插槽:
<template> <div> <span>我是第一個插槽</span> <slot name="yanggb1"></slot> <span>我是第二個插槽</span> <slot name="yanggb2"></slot> </div> </template> <script> export default { name: 'child' } </script>
在父組件中引用該子組件,並通過v-slot:[name]的方式將相應的內容填充到相應的插槽中:
<template> <div> <span>兩個插槽:</span> <child> <template v-slot:yanggb1> <span>yanggb1,</span> </template> <template v-slot:yanggb2> <span>yanggb2</span> </template> </child> </div> </template>
這時候頁面展示的內容就會是【兩個插槽:第一個插槽yanggb1,第二個插槽yanggb2】。
使用默認插槽和具名插槽的注意事項
1.如果子組件中存在多個默認插槽,那麼父組件中所有指定到默認插槽的填充內容(未指定具名插槽),會全部填充到子組件的每個默認插槽中。
2.即使在父組件中將具名插槽的填充順序打亂,只要具名插槽的名字對應上了,填充的內容就能被正確渲染到相應的具名插槽中,一個蘿蔔一個坑。
3.如果子組件中同時存在默認插槽和具名插槽,但是在子組件中找不到父組件中指定的具名插槽,那麼該內容會被直接丟棄,而不會被填充到默認插槽中。
作用域插槽
作用域插槽的概念和使用,相比於前面的默認插槽和具名插槽,會比較難於理解和運用。前面的兩個插槽強調的是填充佔位的【位置】,而作用域插槽強調的則是數據作用的【範圍】。
所謂的作用域插槽,其實就是帶參數(數據)的插槽,即在子組件的插槽中帶入參數(數據)提供給父組件使用,該參數(數據)僅在插槽內有效,父組件可以根據子組件中傳過來的插槽參數(數據)對展示內容進行訂製。
在子組件中放置一個帶參數(數據)的插槽:
<template> <div> <span>插槽中的參數值是</span> <slot :name="yanggb"></slot> </div> </template> <script> export default { name: 'child', data() { return { yanggb: { yanggb1: 'yanggb1', yanggb2: 'yanggb2' } } } } </script>
在父組件中引用該子組件,並通過slot-scope來接受子組件的插槽中傳過來的參數和使用該數據。
<template> <div> <span>作用域插槽:</span> <child> <template slot-scope="yanggb"> {{ yanggb.yanggb1 }} </template> </child> </div> </template>
這時候頁面展示的內容就會是【作用域插槽:插槽中參數值是yanggb1】。
另外,因為在template的{{}}是支援表達式的,這個時候就可以利用子組件傳過來的參數值的不同進行頁面內容的訂製。
<template> <div> <span>作用域插槽:</span> <child> <template slot-scope="yanggb"> {{ yanggb.yanggb1 || '空值' }} </template> </child> </div> </template>
這時候,如果子組件中傳過來的參數是空值,頁面的展示內容就會是【作用域插槽:插槽中參數值是空值】。
作用域插槽的使用場景多種多樣,在各種框架中的應用也是十分廣泛,比如ElementUI中的對表格的某一行或某一列進行展示內容的訂製,就是作用域插槽的一個典型應用場景。
“你在池塘里活得很好,泥鰍很醜但會說喜慶話,癩蛤蟆馬虎但很有趣,田螺是個溫柔的自閉症,小鯽魚是你們共同的女神。有一天你聽說,江河湖海,哪個都要更大,更好。你跳了出去,遇到了美麗的海豚,雄壯的白鯨,婀娜多姿的熱帶魚,的確都是好的。就是偶爾,覺得世界很空,生活很咸。”