1. 程式人生 > >Vuejs:元件 slot 內容分發

Vuejs:元件 slot 內容分發

本文是在官方文件的基礎上,更加細緻的說明,程式碼更多更全。

簡單來說,更適合新手閱讀

(二十八)Slot分發內容

①概述:

簡單來說,假如父元件需要在子元件內放一些DOM,那麼這些DOM是顯示、不顯示、在哪個地方顯示、如何顯示,就是slot分發負責的活。

②預設情況下

父元件在子元件內套的內容,是不顯示的。

例如程式碼:

<div id="app">  
    <children>  
        <span>12345</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<button>為了明確作用範圍,所以使用button標籤</button>"  
            }  
        }  
    });  
</script>  

顯示內容是一個button按鈕,不包含span標籤裡面的內容;

③單個slot

簡單來說,只使用這個標籤的話,可以將父元件放在子元件的內容,放到想讓他顯示的地方。

<div id="app">  
    <children>  
        <span>12345</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<button><slot></slot>為了明確作用範圍,所以使用button標籤</button>"  
            }  
        }  
    });  
</script>  

例如這樣寫的話,結果是:

<button><span>12345</span>為了明確作用範圍,所以使用button標籤</button>

即父元件放在子元件裡的內容,插到了子元件的<slot></slot>位置;

注意,即使有多個標籤,會一起被插入,相當於用父元件放在子元件裡的標籤,替換了<slot></slot>這個標籤。

④具名slot

將放在子元件裡的不同html標籤放在不同的位置

父元件在要分發的標籤裡新增 slot=”name名” 屬性

子元件在對應分發的位置的slot標籤裡,新增name=”name名” 屬性,

然後就會將對應的標籤放在對應的位置了。

示例程式碼:

<div id="app">  
    <children>  
        <span slot="first">12345</span>  
        <span slot="second">56789</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<button><slot name='first'></slot>為了明確作用範圍,<slot name='second'></slot>所以使用button標籤</button>"  
            }  
        }  
    });  
</script>  

顯示結果為:(為了方便檢視,已手動調整換行)

<button>

<span slot="first">12345</span>

為了明確作用範圍,

<span slot="second">56789</span>

所以使用button標籤

</button>

⑤分發內容的作用域:

被分發的內容的作用域,根據其所在模板決定,例如,以上標籤,其在父元件的模板中(雖然其被子元件的children標籤所包括,但由於他不在子元件的template屬性中,因此不屬於子元件),則受父元件所控制。

示例程式碼:

<div id="app">  
    <children>  
        <span slot="first" @click="tobeknow">12345</span>  
        <span slot="second">56789</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        methods: {  
            tobeknow: function () {  
                console.log("It is the parent's method");  
            }  
        },  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<button><slot name='first'></slot>為了明確作用範圍,<slot name='second'></slot>所以使用button標籤</button>"  
            }  
        }  
    });  
</script>  

當點選文字12345的區域時(而不是按鈕全部),會觸發父元件的tobeknow方法。

但是點選其他區域時則沒有影響。

官方教程是這麼說的:

父元件模板的內容在父元件作用域內編譯;子元件模板的內容在子元件作用域內編譯。

⑥當沒有分發內容時的提示:

假如父元件沒有在子元件中放置有標籤,或者是父元件在子元件中放置標籤,但有slot屬性,而子元件中沒有該slot屬性的標籤。

那麼,子元件的slot標籤,將不會起到任何作用。

除非,該slot標籤內有內容,那麼在無分發內容的時候,會顯示該slot標籤內的內容。

如示例程式碼:

<div id="app">  
    <children>  
        <span slot="first">【12345】</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<div><slot name='first'><button>【如果沒有內容則顯示我1】</button></slot>為了明確作用範圍,<slot name='last'><button>【如果沒有內容則顯示我2】</button></slot>所以使用button標籤</div>"  
            }  
        }  
    });  
</script> 

 說明:

【1】name=’first’的slot標籤被父元件對應的標籤所替換(slot標籤內部的內容被捨棄);

【2】name=’last’的slot標籤,因為沒有對應的內容,則顯示該slot標籤內部的內容。

⑦假如想控制子元件根標籤的屬性 

【1】首先,由於模板標籤是屬於父元件的,因此,將子元件的指令繫結在模板標籤裡,是不可以的(因為他歸屬於父元件);

【2】假如需要通過父元件控制子元件是否顯示(例如v-if或者v-show),那麼這個指令顯然是屬於父元件的(例如放在父元件的data下面)。可以將標籤寫在子元件的模板上。

如程式碼:

<div id="app">  
    <button @click="toshow">點選讓子元件顯示</button>  
    <children v-if="abc">  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        data: {  
            abc: false  
        },  
        methods: {  
            toshow: function () {  
                this.abc = !this.abc;  
            }  
        },  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<div>這裡是子元件</div>"  
            }  
        }  
    });  
</script>  

說明:通過父元件(點選按鈕,切換v-if指令的值)控制子元件是否顯示。

【3】假如需要通過子元件,控制子元件是否顯示(比如讓他隱藏),那麼這個指令顯然是屬於子元件的(會將值放在子元件的data屬性下),那麼就不能像上面這麼寫,而是必須放置在子元件的根標籤中。

<div id="app">  
    <button @click="toshow">點選讓子元件顯示</button>  
    <children>  
        <span slot="first">【12345】</span>  
        <!--上面這行不會顯示-->  
    </children>  
</div>  
<script>  
    var vm = new Vue({  
        el: '#app',  
        methods: {  
            toshow: function () {  
                this.$children[0].tohidden = true;  
            }  
        },  
        components: {  
            children: {    //這個無返回值,不會繼續派發  
                template: "<div v-if='tohidden' @click='tohide'>這裡是子元件</div>",  
                data: function () {  
                    return {  
                        tohidden: true  
                    }  
                },  
                methods: {  
                    tohide: function () {  
                        this.tohidden = !this.tohidden;  
                    }  
                }  
            }  
        }  
    });  
</script>  

說明:

點選子元件會讓子元件消失;

點選父元件的按鈕,通過更改子元件的tohidden屬性,讓子元件重新顯示。

子元件的指令繫結在子元件的模板之中(如此才能呼叫);

轉自:https://blog.csdn.net/sinat_17775997/article/details/52484072#comments