一篇文章徹底理解學會Vue插槽

所謂組件的插槽,簡單來說就是在子組件中預留一定的位置,父組件可以向該位置傳遞內容。

基本插槽

子組件預留的位置:

<slot>默認內容</slot>

父組件向子組件分發內容

<!-- 組件包着的內容就是向子組件分發的內容 -->
<組件名稱>要分發的內容</組件名稱>
基本例子
    <div id="test">
     <!-- 使用組件 -->
     <!-- 如果使用子組件的時候沒有傳遞數據,則使用子組件插槽的默認內容 -->
        <btn></btn>
        <!-- 如果使用子組件的時候傳遞有數據,則使用父組件傳遞的內容 -->
        <btn>這是我的按鈕</btn>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('btn', {
            // 通過<slot></slot>預留插槽
            template: `<button><slot>按我</slot></button>`
        })
        new Vue({
            el: '#test'
        })
    </script>

具名插槽

所謂具名插槽,就是指有名字的插槽,就是子組件在預留插槽位置的時候,可以設置插槽的名字,父組件在向子組件分發內容的時候,可以根據名字向不同的插槽分別分發內容

    <div id="test">
       <xxx>你好嗎</xxx>
       <div>****************</div>
       <xxx>
           <span slot="boy">學習Java從入門到放棄</span>
           <span slot="girl">數據庫從刪庫到跑路/span>
           <span slot="boy">學習Vue從入門到大神</span>
           66666
       </xxx>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('xxx', {
            // 通過<slot></slot>預留插槽
            template: `<div>
                        <div style="color: green;">
                            <slot name="boy"></slot>
                        </div>
                        <div style="color: pink;">
                            <slot name="girl"></slot>
                        </div>
                        <div style="color: blue;">
                            <slot></slot>
                        </div>
                    </div>`
        })
        new Vue({
            el: '#test'
        })
    </script>

從上面的例子我們可以看出,組件在預留插槽的時候是這樣的:

		<div>
        <div style="color: green;">
            <!-- 名字爲boy的插槽 -->
            <slot name="boy"></slot>
        </div>
        <div style="color: pink;">
            <!-- 名字爲girl的插槽 -->
            <slot name="girl"></slot>
        </div>
        <div style="color: blue;">
            <!-- 沒名字的插槽 -->
            <slot></slot>
        </div>
    </div>

父組件向子組件分發內容是這樣的:

		<div id="test">
        <xxx>你好啊</xxx>
        <div>****************</div>
        <xxx>
            <span slot="boy">喫飯</span>
            <span slot="girl">睡覺</span>
          	<span slot="boy">打豆豆</span>
            666
        </xxx>
    </div>

分發規則就是:父組件分發內容時,是按照名字分發到對應的插槽中,如果分發的內容沒有名字,就是分發到無名字的子組件插槽。

使用template標籤進行批量具名分發

對於一次性需要分發的內容比較多的時候,可以使用一個叫template的標籤,一塊分發。

    <div id="test">
        <xxx>
            <!-- 對於多個,我們可以使用一個固定的template標籤進行分發 -->
            <template slot="boy">
                <span>喫飯</span>
                <span>睡覺</span>
            </template>
            <span slot="girl">打豆豆</span>
            666
        </xxx>
    </div>

作用域插槽

作用域插槽一般用在子組件的內容需要在父組件中處理的時候

    <div id="test">
        <xxx>
            <!-- sonData是子組件綁定的數據,名字可以自己定 -->
            <template slot-scope="sonData">
               <span v-if="sonData.king.camp == '蜀國大帝'" style="color: red;">{{sonData.king.name}}  --- {{sonData.king.camp}}</span>
               <span v-else>{{sonData.king.name}}  --- {{sonData.king.camp}}</span>
            </template>
        </xxx>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.component('xxx', {
            data() {
                return {
                    kings: [
                        {name: '曹操', camp: '魏國大帝'},
                        {name: '孫權', camp: '吳國大帝'},
                        {name: '劉備', camp: '蜀國大帝'},
                    ]
                }
            },
            template: `<ul>
                            <!-- 子組件定義插槽的同時,綁定一個屬性(名字自定),綁定的數據可以被父組件捕獲到 -->
                            <li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li>
                        </ul>`
        })
        new Vue({
            el: '#test'
        })
    </script>

從例子中我們可以看出,在子組件中定義插槽的時候,可以綁定一個屬性(名字自定),該屬性綁定的數據可以被父組件捕獲到。

template: `<ul><li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li></ul>`

在父組件中,可以通過 slot-scope 屬性捕獲到子組件綁定的數據,然後我們就可以自由的修改數據,修改後的數據會再次分發到子組件中

<xxx>
  <!-- sonData是子組件綁定的數據,名字可以自己定 -->
  <template slot-scope="sonData">
    <!--這裏的king就是子組件綁定的屬性名,這個要一致-->
    <span v-if="sonData.king.camp =='蜀國大帝'" style="color:red;">{{sonData.king.name}}</span>
    <span v-else>{{sonData.king.name}}</span>
  </template>
</xxx>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章