vue組件詳解(四)——使用slot分發內容

1、什麼是slotapp

在使用組件時,咱們經常要像這樣組合它們:spa

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

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

注意兩點:component

1.< app>組件不知道它的掛載點會有什麼內容。掛載點的內容是由<app >的父組件決定的。blog

2.<app> 組件極可能有它本身的模板。事件

props 傳遞數據、events 觸發事件和slot 內容分發就構成了Vue 組件的3 個API 來源,再複雜的組件也是由這3 部分構成的。作用域

 

 2、做用域it

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

這裏的message 就是一個slot ,可是它綁定的是父組件的數據,而不是組件<child-component>的數據。io

父組件模板的內容是在父組件做用域內編譯,子組件模板的內容是在子組件做用域內編譯。如:編譯

        <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
    }
});

這裏的狀態showChild 綁定的是父組件的數據,若是想在子組件上綁定,那應該是:

       <div id="app15">
            <child-component></child-component>
        </div>
Vue.component('child-component',{
    template: '<div v-show="showChild">子組件</div>',
    data: function(){
        return {
            showChild: true
        }
    }
});

所以, slot 分發的內容,做用域是在父組件上的。

 

3、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'
});

渲染結果爲:

<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'
});

渲染結果爲:

            <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 ,父組件內多餘的內容片斷都將被拋棄。

 

4、做用域插槽

做用域插槽是一種特殊的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'
});

渲染結果爲:

<div id=」app18」>
    <div class=」container」>
        <p>來組父組件的內容</p>
        <p>來自子組件的內容</p>
    </div>
</div>

觀察子組件的模板,在<slot>元素上有一個相似props 傳遞數據給組件的寫法msg=」 xxx 」,將數據傳到了插槽。

父組件中使用了<template>元素,並且擁有一個scope=」props 」的特性,這裏的props只是一個臨時變量,就像v-for= 」 item in items 裏面的item 同樣,template 內能夠經過臨時變量props訪問來自子組件插槽的數據msg 。

相關文章
相關標籤/搜索