Vue-Slot的使用和理解

Slot

Slot=>內容分發,佔位元素spa

父級模板裏的全部內容都是在父級做用域中編譯的;子模板裏的全部內容都是在子做用域中編譯的。Slot分發的內容,做用域是在父組件上

1.Vue2.6版本前的舊特性用法

1.1不具名slot

父組件內使用子組件code

<children>
    <p>我是第一行</p>
    <p>我是第二行</p>
</children>

子組件模板內容對象

<div>
    <p>template div 內容</p> 
    <!-- <slot>slot標籤內的內容</slot>slot外div內的內容 -->
</div>

渲染過程: 模板內容直接替換childre中的內容作用域

<div>
    <p>template div p 內容</p>
</div>

接上 啓用slot後的渲染結果it

<div>
    <p>template div 內容</p>
    <p>我是第一行</p>
    <p>我是第二行</p>
    <!--複製被調用子組件內的內容並替換<slot></slot>自身-->
    slot外div內的內容<!--該內容按從上到下被渲染-->      
</div>

渲染過程: 按子組件模板從上至下渲染,先將<p>template div 內容</p>渲染出來,緊接着讀取到slot標籤當即複製被調用子組件內的內容並替換<slot></slot>自身,而後渲染子組件模版內剩餘io

1.2具名slot

父組件內使用子組件編譯

<children>
    <p>我是第一行</p>
    <p>我是第二行</p>
    <slot>第一個slot</slot>
    <slot>第二個slot</slot>
    <h2 slot="header">頭部在這</h2>
    <p>中間在這</p>
    <div slot="footer">
        <div>底部在這</div>
    </div>
</children>

子組件模板內容table

<div>
    <slot></slot>
    <h2 slot="header">h2 slot=header</h2><!--不報錯,應該被認爲常規元素,會被渲染到不具名slot區域-->
    <slot name="header"></slot><!--在父組件中搜查匹配 帶有名叫"header"slot的元素並複製替換本處元素-->  
    <slot name="footer"></slot><!--在父組件中搜查匹配 帶有名叫"footer"slot的元素並複製替換本處元素-->  
</div>

渲染成:ast

<div>
    <p>我是第一行</p>
    <p>我是第二行</p> 第一個slot 第二個slot <p>中間在這</p>
    <h2 slot="header">h2 slot=header</h2>
    <h2>頭部在這</h2>
    <div>
        <div>底部在這</div>
    </div>
</div>

渲染過程:讀取到slot標籤後將被調用的子組件中沒有被具名插槽包裹的內容及子組件模版內的常規內容替換slot標籤所在區域並按順序渲染,讀到具名slot則在被調用的子組件中查找與之name對應的內容複製替換對應的具名插槽並渲染function

1.3做用域插槽 slot-scope

2.6以前 ==>slot scope=」別名」
在父組件內使用 slot-scope 並使用傳入的數據
將<span v-for="item in aaa.shuju">{{item}}</span>複製替換子組件的<slot></slot>,並將「shuju」做爲receiveData的新屬性(相似這個意思),此時receiveData.shuju就等同於子組件中返回的data對象

<template slot-scope="receiveData">
    <div>
    <span v-for="item in receiveData.shuju">{{item}}</span>
   </div>
</template>

在子組件內設定傳入的值並在slot上綁定須要傳入的值
子組件內

模板:     
<div>
     <slot :shuju="data"></slot>
</div>

其餘:

data:function(){
return{
  data:['zhangsan','lisi','wangwu','maliu','qianqi','zhouba']
          }
     }

最終渲染成:

<div>
    <h3>這裏是子組件</h3>
    <div>
        <span>zhangsan</span><span>lisi</span><span>wangwu</span><span>maliu</span><span>qianqi</span><span>zhouba</span>
    </div>
</div>

2.Vue2.6版本及之後的新特性用法

2.1 不具名插槽

父組件內使用子組件

<children>
    <template v-slot> <!--此處的v-slot等同於 v-slot:default-->
        <div>
            template v-slot中的內容
        </div>
    </template>
</children>

子組件模板內

<div>
    <slot></slot>     
</div>

最終渲染成:

<div>
     <div>
        template v-slot中的內容
     </div>
</div>

渲染過程基本一致

2.2 具名插槽

2.6新特性 v-slot 只能被用於組件或者模板 上方使用v-slot
父組件內使用子組件

<children>
    <template v-slot:header>
        hahaha
    </template>
    <template v-slot:footer>

        腳在這兒
    </template>
    <template v-slot:header>頭部在這</template>
    <!--此處會覆蓋上面同名-->
    <p>中間在這</p>
    <template v-slot:footer>
        <!--此處會覆蓋上面同名-->
        <div>底部在這</div>
    </template>
</children>

子組件模板內

<div>
    <slot></slot>
    <slot name="header"></slot>
    <slot name="footer"></slot>
</div>

最終渲染成:

<div>
    <p>中間在這</p> 
    頭部在這 
    <div>底部在這</div>
</div>

渲染過程基本一致
注意:多個同名具名插後面的覆蓋前面的,只會有一個起效!

2.3做用域插槽

v-slot
在父組件內使用 v-slot=」xxx」 並傳入的數據

<children>
        <template v-slot:header>
            hahaha
        </template>
        <template v-slot:footer>

            腳在這兒
        </template>
        <template v-slot:header>頭部在這</template>
        <!--此處會覆蓋上面同名-->
        <p>中間在這</p>
        <template v-slot:footer="receiveData">
            <!--此處會覆蓋上面同名-->
            <div>底部在這</div>
            <div>{{receiveData.sendData.firstName}}+{{receiveData.sendData.lastName}}</div>
        </template>
</children>

子組件模板內

<div>
    <slot></slot>
    <slot name="header"></slot>
    <slot name="footer" :sendData="userInfo"></slot>
</div>

最終渲染成:

<div>
    <p>中間在這</p> 
    頭部在這 
    <div>底部在這</div>
    <div>Brain+Lu</div>
</div>

渲染過程基本一致

3.理解及結論

默認(後備)內容[通常指子組件模板內的<slot>默認(後備)內容</slot>]生效的狀況:在父組件內使用的子組件內不包含可渲染內容的狀況下會被渲染出來。
渲染順序:在父組中被調用的子組件外的內容有線渲染,而後子組件模板內從上至下渲染。
Slot執行過程:子組件的模板把父組件中的內容(<children>內容</children>)選擇性複製而後替換自己。
Slot-不具名插槽==>子組件模板內各個<slot></slot>都會把父組件中除具名插槽包裹的其餘內容複製一份並替換自身(<slot></slot>)位置
Slot-具名插槽==>子組件模板內各個<slot name="xxx"></slot>都會把父組件中的與匹配的具名插槽包裹的其餘內容複製一份並替換自身(<slot></slot>)位置再渲染
v-slot寫法同時存在多個同名具名插槽,寫在最後的那個起效
同時存在兩種寫法的狀況下 新寫法的渲染優先級更高,不管是否具名都會覆蓋掉就寫法

<template v-slot:footer>
     template v-slot
</template>
<p slot="footer">slot=footer</p>   <!--此處不會被渲染,不論寫在v-slot以前仍是以後-->

目前還未應用於實際場景,聽聞Element的table組件和Button組件彷佛有用到slot,暫未探究,有興趣的小夥伴能夠去看看;有實際應用也可告訴我。
注:結論等均是感性認知,不必定是正確的,只是方便理解(也許只是本身)

相關文章
相關標籤/搜索