1. 程式人生 > >深入淺出vue元件之使用slot分發

深入淺出vue元件之使用slot分發

在實際專案開發當中,時常會把父元件的內容與子元件自己的模板混合起來使用。而這樣的一個過程在Vue中被稱為內容分發。也常常被稱為**slot(插槽)**。今天主要來介紹了vue元件詳解之使用slot分發內容及Vue元件中slot的用法

一、什麼是slot

在使用元件時,我們常常要像這樣組合它們:

<app>
 <app-header></app-header>
 <app-footer></app-footer>
</app>

當需要讓元件組合使用,混合父元件的內容與子元件的模板時,就會用到slot , 這個過程叫作內容分發( transclusion )。

注意兩點:

  • < app>元件不知道它的掛載點會有什麼內容。掛載點的內容是由<app >的父元件決定的。
  • <app> 元件很可能有它自己的模板。

props 傳遞資料、events 觸發事件和slot 內容分發就構成了Vue 元件的3 個API 來源,再複雜的元件也是由這3 部分構成的。

二、作用域

<child-component>
 {{ message }}
</child-component>

這裡的message 就是一個slot ,但是它繫結的是父元件的資料,而不是元件<child-component>的資料。 父元件模板的內容是在父元件作用域內編譯,子元件模板的內容是在子元件作用域內編譯。如:

<div id="app15">
      <child-component v-show="showChild"></child-component>
    </div>
Vue.component('child-component',{
  template: '<div>子元件</div>'
});
var app15 = new Vue({
  el: '#app15',
  data: {
    showChild: true
  }
});//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860

這裡的狀態showChild 繫結的是父元件的資料,如果想在子元件上繫結,那應該是:

 <div id="app15">
      <child-component></child-component>
    </div>
Vue.component('child-component',{
  template: '<div v-show="showChild">子元件</div>',
  data: function(){
    return {
      showChild: true
    }//歡迎加入前端全棧開發交流圈一起學習交流:864305860
  }//面向1-3年前端人員
});//幫助突破技術瓶頸,提升思維能力

因此, slot 分發的內容,作用域是在父元件上的。

三、slot用法

3.1 單個slot

在子元件內使用特殊的<slot>元素就可以為這個子元件開啟一個slot(插槽),在父元件模板裡,插入在子元件標籤內的所有內容將替代子元件的<slot> 標籤及它的內容。

<div id="app16">
      <my-component16>
        <p>分發的內容</p>
        <p>更多分發的內容</p>
      </my-component16>
    </div>
Vue.component('my-component16',{
  template: '<div>' +
        '<slot><p>如果父元件沒有插入內容,我將作為默認出現<</p></slot>' +    //預留的slot插槽
       '</div>'
});
var app16 = new Vue({
  el: '#app16'
});//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860

渲染結果為:

<div id=”app16”>
  <div>
    <p>分發的內容<p>
    <p>更多分發的內容<p>
  </div>
</div>

子元件child-component 的模板內定義了一個<slot>元素,並且用一個<p>作為預設的內容,在父元件沒有使用slot 時,會渲染這段預設的文字;如果寫入了slot, 那就會替換整個<slot> 。 3.2具名slot

給<slot> 元素指定一個name 後可以分發多個內容,具名Slot 可以與單個slot 共存。

<div id="app17">
      <my-component17>
        <h3 slot="header">標題</h3>
        <p>正文內容</p>
        <p>更多正文內容</p>
        <h3 slot="footer">底部資訊</h3>
      </my-component17>
    </div>
Vue.component('my-component17',{
  template: '<div class="container">' +
         '<div class="header">' +
          '<slot name="header"></slot>' +
         '</div>' +
         '<div class="main">' +
          '<slot></slot>' +
         '</div>'+
         '<div class="footer">' +
          '<slot name="footer"></slot>' +
         '</div>'+
       '</div>'
});
var app17 = new Vue({
  el: '#app17'
});//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860

渲染結果為:

<div id="app17">
       <div class="container">
         <div class="header">
           <h3>標題</h3></div>
         <div class="main"> 
           <p>正文內容</p> 
           <p>更多正文內容</p> 
         </div>
         <div class="footer">
           <h3>底部資訊</h3>
         </div>
       </div>
     </div>

子元件內聲明瞭3 個<s lot>元素,其中在<div class=” main >內的<slot> 沒有使用name 特性,它將作為預設slot 出現,父元件沒有使用slot 特性的元素與內容都將出現在這裡。 如果沒有指定預設的匿名slot ,父元件內多餘的內容片段都將被拋棄。

四、作用域插槽

作用域插槽是一種特殊的slot ,使用一個可以複用的模板替換己渲染元素。 看一個例子:

<div id="app18">
      <my-component18>
        <template scope="props">
          <p>來自父元件的內容</p>
          <p>{{props.msg}}</p>
        </template>
      </my-component18>
    </div>
Vue.component('my-component18',{
  template: '<div class="container"><slot msg="來自子元件的內容"></slot></div>'
});
var app18 = new Vue({
  el: '#app18'
});//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860

觀察子元件的模板,在<slot>元素上有一個類似props 傳遞資料給元件的寫法msg=” xxx ”,將資料傳到了插槽。 父元件中使用了<template>元素,而且擁有一個scope=”props ”的特性,這裡的props只是一個臨時變數,就像v-for= ” item in items 裡面的item 一樣,template 內可以通過臨時變數props訪問來自子元件插槽的資料msg 。

下面看下Vue元件中slot的用法

主要是讓元件的可擴充套件性更強。

  1. 使用匿名slot
//定義元件my-component
<div class="myComponent">
<slot></slot>
</div>
//使用方法
<my-component>
<p>我就是slot的替代內容,我這裡可以放任何標籤元素哦</p>
</my-component>
  1. 給slot加個名字
//定義元件my-component
<div class="myComponent">
<slot></slot>
</div>
//使用方法
<my-component>
<p slot="myslot">
我就是slot的替代內容,我這裡可以放任何標籤元素哦
這裡需要注意如果不加上 slot="myslot" 就會報錯
</p>
</my-component>

如果不在有slot的元件里加入任何標籤,slot什麼都不會顯示的。 結語

感謝您的觀看,如有不足之處,歡迎批評指正。