1. 程式人生 > >Vue元件之--slot內容分發

Vue元件之--slot內容分發

以前,Vue元件總是一個個的空標籤的形式出現的,那麼如果說元件標籤裡面有內容,那麼要獲取這些內容要怎麼辦呢?

Vue提供了一個解決方案:slot內容分發,其作用就是用來獲取元件中的原內容(就是元件標籤內部的內容)。

用法分為兩種情況:當元件內的原內容結構比較簡單的時候可以使用單一slot,原內容結構比較複雜的時候使用具名slot;

單一slot:在元件模板合適的位置插入slot元件即可;

 <div id="container" v-cloak>
     <my-compo>你好,2018!</my-compo>
     <!-- 在這裡元件的原內容是:你好,2018 ,比較簡單-->
 </div>
 <!-- 在元件模板中獲原內容 -->
  <template id="myCompon">
     <div class="content">
         <h3>{{house.price}}</h3>
         <slot>沒有原內容</slot>
         <!-- 當沒有原內容的時候就會顯示“沒有原內容”,有的話就會被替換成原內容 -->
     </div>
 </template>
具名slot: 給你想獲取的原內容部分指定一個屬性`slot = "值"`,然後在在元件的模板中的合適位置插入一個slot元素,設定`name= "值"`即可。例如:

 <div id="container" v-cloak>
     <my-compon1>
         <div slot = "smile">
             <i>哈哈</i>
         </div>
         <ul slot="list">
             <li>111</li>
             <li>222</li>
             <li>333</li>
         </ul>
     </my-compon1>
     <!-- 原內容結構比較複雜 -->
     <!-- 獲取原內容中你想要的那一部分 -->
 </div>
 <!-- 獲取你想要的那一部分 -->
 <template id="myCompon1">
     <div>
         <slot name="smile"></slot>
         <!-- 這個時候,在元件內部含有屬性slot="smile"的元素包裹的原內容就會被顯示到這裡 -->
         <h4>{{clothes}}</h4>
         <!-- 同上 -->
         <slot name="list"></slot>
     </div>
 </template>

作用域插槽slot:

首先要將子元件的資料傳遞給子元件模板中的slot插槽(v-bind繫結屬性):

<!-- 子元件模板 -->
    <template id="sonTemplate">
        <div class="son-class">
            <slot v-bind:heheda="computer.price" v-bind:materials="computer.material"></slot>
        </div>
    </template>
然後在父元件模板中具有特殊特性 slot-scope的 <template> 元素必須存在,表示它是作用域插槽的模板( 也就是說被<template slot-scope></template>元素包圍內容就是slot的模板,在渲染的時候slot就會被渲染成該模板內容),slot-scope的值將被當作一個臨時的變數名,此變數用來接收從子元件傳遞過來的props物件(就是一個數據物件);
<!-- 父元件模板 -->
    <template id="compo">
        <div>
            <h3>{{greeting}}</h3>
             <my-app-son>
                 <!-- 這裡  <template slot-scope = "props">就是slot插槽的模板,也就是說在渲染的時候slot會被渲染成該模板包裹著的內容-->
                <template slot-scope = "props">
                    <!-- 這裡的props就是一個包含有屬性heheda和materials的物件 -->
                    <h3>{{greeting}}</h3>
                    <h4>{{props.heheda}}</h4>
                    <h4>{{props.materials}}</h4>
                </template>
             </my-app-son>
        </div>
    </template>
在 2.5.0+,slot-scope 能被用在任意元素或元件中而不再侷限於 <template>
作用域插槽更典型的用例是在列表元件中,允許使用者自定義如何渲染列表的每一項:

<!-- <my-awesome-list>是一個子元件,子元件繫結的屬性items,資料是來源於父元件 -->
<my-awesome-list :items="items">
  <!-- 作用域插槽也可以是具名的 -->
  <li
    slot="item"
    slot-scope="props"
    class="my-fancy-item">
    {{ props.text }}
  </li>
</my-awesome-list>
列表元件的模板:
<ul>
    <!--子元件模板, 這裡的items應該是通過父子通訊獲得的 -->
  <slot name="item" v-for="item in items" :text="item.text"></slot>
</ul>
注意:在分析元件+slot具體出來的內容是什麼的時候,可以先將元件內部的原內容給剝離出來,在此基礎上進行分析在沒有原內容的時候元件將會是什麼樣子,
然後再在分析結果的基礎上將原內容加上,再進行分析,最後得出結果