Vue 之 slot(插槽)

前言:

vue中關於插槽的文檔說明很短,語言又寫的很凝練,再加上其和methods,data,computed等經常使用選項在使用頻率、使用前後上的差異,這就有可能形成初次接觸插槽的開發者容易產生「算了吧,回頭再學,反正已經能夠寫基礎組件了」的想法,因而就關閉了vue的說明文檔。html

實際上,插槽的概念很簡單,下面經過分三部分來說。這三部分也是按照vue說明文檔的順序來寫的。vue

進入這三部分以前,先讓還沒接觸過插槽的同窗對什麼是插槽有一個簡單的概念:插槽,也就是slot,是組件的一塊HTML模板,這塊模板顯示不顯示、以及怎樣顯示由父組件來決定。 實際上,一個slot最核心的兩個問題在這裏就點出來了,是顯示不顯示怎樣顯示web

因爲插槽是一塊模板,因此,對於任何一個組件,從模板種類的角度來分,其實均可以分爲非插槽模板插槽模板兩大類。 非插槽模板指的是html模板,好比‘div、span、ul、table’這些,非插槽模板的顯示與隱藏以及怎樣顯示由組件自身控制;插槽模板是slot,它是一個空殼子,由於它的顯示與隱藏以及最後用什麼樣的html模板顯示由父組件控制。可是插槽顯示的位置卻由子組件自身決定,slot寫在組件template的什麼位置,父組件傳過來的模板未來就顯示在什麼位置bash

 

1、理解vue中的slot

官網上對slot的理解是:post

「Vue實現了一套內容分發的API,這套API基於當前的Web Components規範草案,將slot元素做爲承載分發內容的接口」。flex

  在參考了不少資料以後,如下總結一下我對slot的理解:   slot的意思是插槽,Vue使用slot的做用是作內容分發。所謂的內容分發其實就是將父組件的內容放到子組件指定的位置叫作內容分發。   在咱們的電腦主板上也有各類各樣的插槽,有插CPU的,有插顯卡的,有插內存的,有插硬盤的。咱們能夠理解slot爲要佔出當前的位置,方便咱們插入內容。或者能夠這樣理解:要去吃飯了,兒子先去佔座,而後等他爸爸來了再一塊兒吃。   Vue的插槽分爲匿名插槽(單個插槽/默認插槽)、具名插槽、做用域插槽(帶數據的插槽)。 ####匿名插槽(單個插槽/默認插槽)ui

  • 無name屬性
  • 在組件中只可使用一次
  • 父組件提供樣式和內容
<!-- 父組件-->
<template>
    <div class="father"> <h3>這裏是父組件</h3> <chlid> <div class="tmp1"> <span>Leaf 1</span> <span>Leaf 2</span> <span>Leaf 3</span> <span>Leaf 4</span> <span>Leaf 5</span> </div> </child> </div> </template> <script> import Child from '@/components/child' export default { components:{ child:child } } </script> <style> .tmp1 span{ width: 50px; height: 50px; border: 1px solid black; } </style> 複製代碼
<!--子組件-->
<template>
    <div>
        <slot></slot>
        <h2>child子組件部分</h2>
    </div>
</template>
複製代碼

最終呈現效果:spa

image.png 若是改變子組件中的位置:

 

<template>
    <div>
        <h2>child子組件部分</h2>
      <slot></slot>
    </div>
</template>
複製代碼

改變slot位置後的最終呈現效果以下:code

image.png

 

只有在父組件的child下寫了html模板,才能在子組件指定的位置放父組件的內容。插槽最後顯示不顯示是看父組件有沒有在child下寫模板,像下面同樣:component

<child>
    html模板
</child>
複製代碼

####具名插槽

  • 有name屬性
  • 在組件中可使用N次
  • 父組件經過html模板上的slot屬性關聯具名插槽
  • 沒有slot屬性的html模板默認關聯匿名模板
  • 父組件提供樣式和內容
<!--父組件-->
<template>
    <div class="father"> <h3>這裏是父組件</h3> <chlid> <div class="tmp1" slot="up"> <span>Leaf 1</span> <span>Leaf 2</span> <span>Leaf 3</span> <span>Leaf 4</span> <span>Leaf 5</span> </div> <div class="tmp1" slot="down"> <span>Leaf 6</span> <span>Leaf 7</span> <span>Leaf 8</span> <span>Leaf 9</span> <span>Leaf 10</span> </div> </child> </div> </template> <script> import Child from '@/components/child' export default { components:{ child:child } } </script> <style> .tmp1 span{ width: 50px; height: 50px; border: 1px solid black; } </style> 複製代碼
<!--子組件-->
<template>
    <div>
        <slot name="up"></slot> <h2>chlid子組件部分</h2> <slot name="down"></slot> </div> </template> 複製代碼

最終呈現效果:

image.png ####做用域插槽(帶數據的插槽)

 

  • 父組件只提供樣式,子組件提供內容
  • 在slot上面綁定數據
  • 子組件的值能夠傳給父組件使用
  • 父組件展現子組件數據有3種方式:flex顯示列表顯示直接顯示
  • 使用slot-scope必須使用template
  • scope返回的值是slot標籤上返回的全部屬性值,而且是一個對象的形式保存起來
  • slot有兩個屬性,一個row,另外一個是index
<!--父組件-->
<template>
    <div class="father"> <h3>這裏是父組件</h3> <chlid> <!-- 第一次使用:用flex展現數據 --> <template slot-scope="user"> <div class="tmp1"> <span v-for="(item,index) in user.data" :key="index">{{item}}</span> </div> </template> <!-- 第二次使用:用列表展現數據 --> <template slot-scope="user"> <ul> <li v-for="(item,index) in user.data" :key="index">{{item}}</li> </ul> </template> <!-- 第三次使用:直接顯示 --> <template slot-scope="user"> {{user.data}} </template> </child> </div> </template> <script> import Child from '@/components/child' export default { components:{ child:child } } </script> <style> .tmp1 span{ width: 50px; height: 50px; border: 1px solid black; } </style> 複製代碼
<!--子組件-->
<template>
    <div>
        <h2>chlid子組件部分</h2>
        <slot :data="data"></slot> </div> </template> <script> export default { props: ["message"], data () { return { data: [''小莊','CC','小張','小林','Leaf','Bob'] } } } </script> 複製代碼

經過3種方式顯示數據的最終呈現效果分別以下: 一、flex顯示

image.png 二、列表顯示 image.png 三、直接顯示 image.png

 

這裏咱們所看到的數據「'小莊','CC','小張','小林','Leaf','Bob'」都是子組件data提供的數據,父組件若是要使用這些數據必需要經過template模板結合slot-scope來呈現。

這裏只是將本身學到的知識作一個總結,方便本身記憶和查閱,可能會有錯,望大神指點!

做者:Leaf_hyc 連接:https://juejin.im/post/5c83aa1b5188257ddb6af526 來源:掘金 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索