8.Vue元件三---slot插槽

盛開的太陽發表於2021-03-02

主要內容: 

1. 什麼是插槽

2. 元件的插槽

3. 插槽的使用方法

4. 插槽的具名

5. 變數的作用域

6. slot的作用域


 

一. 什麼是插槽呢?

1. 生活中的插槽有哪些呢?

usb插槽, 插線板插槽

2. 插槽有什麼作用?

同樣的插線板, 可以插電視機, 電冰箱, 洗衣機
電腦的usb介面, 可以查滑鼠, 插鍵盤, 還可以外接行動硬碟
插槽的擴充套件性更強.

二. 元件的插槽

1. 作用: 讓元件的更加具有擴充套件性

例: 我們一個網站有很多搜多功能. 每一個頁面的搜尋樣式,文案可能都不一樣.
搜尋欄由背景底色, 左側文案, 搜尋樣式, 右側搜尋按鈕等幾部分組成
每一個搜尋欄的這幾個部分可能都不一樣, 這樣, 我們就可以將其定義為一個元件, 然後, 將變化的部分定義為插槽.
在不同的頁面, 我們需要什麼樣的樣式就可以往插槽中定義什麼樣內容

 

2. 如何封裝元件?

抽取共性, 保留不同.
將共性抽取到元件中, 然後不同的地方暴露為插槽,一旦預留了插槽, 就可以根據需求, 決定插槽的內容

 

三. 插槽的使用方法

1. 插槽的定義

在模板中使用<slot></slot>標籤定義插槽
可以給插槽設定一個預設值, 插槽裡可以有多個值

2. 插槽的呼叫

我們可以在呼叫元件的時候, 在組建中直接定義內容

3. 插槽的基本使用方法 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <comp1><button>插槽裡放了一個按鈕</button></comp1>
    <br>
    <comp1><p>插槽裡放了一個p標籤</p></comp1>
    <br>
    <comp1>
            <span>插槽裡放了一個span標籤</span><span>, 又放了一個span標籤</span></comp1>
    <br>
    <comp1></comp1><br>

</div>
<template id="comp1">
    <div>
        <p>這是一個模板</p>
        <slot><button>這是插槽預設的按鈕</button></slot>
    </div>
</template>
<script src="../../js/vue.js"></script>
<script>
    Vue.component("comp1", {
        template: "#comp1"
    })

    const app = new Vue({
        el: "#app",
        data: {
            message:"hello"
        }
    })
</script>
</body>
</html>

第一步: 定義了一個new Vue()模板

const app = new Vue({
        el: "#app",
        data: {
            message:"hello"
        }
    })

 

第二步: 定一個了一個元件. 並在元件中使用slot設定插槽. 這個插槽有一個預設值. 是一個button

<template id="comp1">
    <div>
        <p>這是一個模板</p>
        <slot><button>這是插槽預設的按鈕</button></slot>
    </div>
</template>

 

第三步: 呼叫元件, 並定製個性化插槽內容

<div id="app">
    <comp1><button>插槽裡放了一個按鈕</button></comp1>
    <br>
    <comp1><p>插槽裡放了一個p標籤</p></comp1>
    <br>
    <comp1>
            <span>插槽裡放了一個span標籤</span><span>, 又放了一個span標籤</span>
  </comp1> <br> <comp1></comp1><br> </div>

案例效果

8.Vue元件三---slot插槽 

四. 插槽的具名

如果有多個插槽, 想要分別替換每一個插槽, 應該怎麼辦呢?

可以分兩步:

第一步: 給插槽設定一個名字
第二步: 替換的時候指定插槽的名字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <comp1></comp1>
    <br> ---------------- <br>
    <comp1><p slot="second">替換第二個插槽的預設值</p></comp1>
    <br> -----------------<br>
    <comp1><p>不設定名字,將不會替換</p></comp1>
    <br> <br>

</div>
<template id="comp1">
    <div>
        <p>這是一個模板</p>
        <slot name="zero"><button>這是插槽預設的按鈕</button></slot> <br>
        <slot name="first"><span>第一個插槽</span></slot> <br>
        <slot name="second"><span>第二個插槽</span></slot> <br>
        <slot name="third"><span>第三個插槽</span></slot> <br>
    </div>

</template>
<script src="../../js/vue.js"></script>
<script>
    Vue.component("comp1", {
        template: "#comp1"
    })

    const app = new Vue({
        el: "#app",
        data: {
            message:"hello"
        }
    })
</script>
</body>
</html>

第一步: 定義元件, 並設定四個插槽, 給每個插槽定義一個名字

<template id="comp1">
    <div>
        <p>這是一個模板</p>
        <slot name="zero"><button>這是插槽預設的按鈕</button></slot> <br>
        <slot name="first"><span>第一個插槽</span></slot> <br>
        <slot name="second"><span>第二個插槽</span></slot> <br>
        <slot name="third"><span>第三個插槽</span></slot> <br>
    </div>

</template>

第二步: 呼叫元件, 指定替換插槽的內容

<comp1><p slot="second">替換第二個插槽的預設值</p></comp1>

8.Vue元件三---slot插槽

 

 

 五. 變數的作用域

1. 在vue例項中定義的data變數, 作用域都是vue例項
2. 在模板中定義的變數, 作用域是模板範圍內

看下面的案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <p>物件的作用域</p>
        <comp1 v-show="isShow"></comp1>
    </div>
    <template id="comp1">
        <div>
            <p>這是一個模板</p>
            <button v-show="isShow">按鈕</button>
        </div>
    </template>
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                message:"hello",
                name: "vue物件裡的name",
                isShow: true
            },
            components: {
                comp1: {
                    template: comp1,
                    data() {
                        return {
                            "name": "模板裡的name",
                            isShow: false
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>

第一步: 定義了一個vue物件, 在父元件中定義一個變臉isShow為true, 在子元件中定一個一個變數isShow:false.

const app = new Vue({
            el: "#app",
            data: {
                message:"hello",
                name: "vue物件裡的name",
                isShow: true
            },
            components: {
                comp1: {
                    template: comp1,
                    data() {
                        return {
                            "name": "模板裡的name",
                            isShow: false
                        }
                    }
                }
            }
        })

 

第二步: 在模板中使用isShow變數. 這裡使用的是模板中定義的isShow變數

    <template id="comp1">
        <div>
            <p>這是一個模板</p>
            <button v-show="isShow">按鈕</button>
        </div>
    </template>

 

第三步: 在dom元素中中使用isShow變數, 這裡的作用域是父元件

<div id="app">
        <p>物件的作用域</p>
        <comp1 v-show="isShow"></comp1>
    </div>

父元件的isShow是true, 所以, 會顯示子元件的內容. 子元件的isShow是false, 所以不會顯示button按鈕

8.Vue元件三---slot插槽

 

 

 效果和我們預期的一樣.

總結:

  • 父元件模板的所有東西都會在父級作用域內編譯; 子元件模板的所有東西都會在子級作用域內編譯
  • <comp1 v-show="isShow"></comp1>整個元件的使用過程是在父元件中出現的, 所以它的作用域是父元件

 

六. slot的作用域

 

 

首先, 我們建立一個Vue例項, 然後在Vue的data中定義一個books, 在元件中定義一個books
然後, 在模板中定義一個插槽, 遍歷books. 我們發現呼叫的是元件中的books

  <template id="comp1">
        <slot>
            <div>
                <p>這是一個模板</p>
                <ul>
                    <li v-for="item in books">{{item}}</li>
                </ul>
            </div>
        </slot>
    </template>
    <script src="../../js/vue.js"></script>
    <script>
       
        const app = new Vue({
            el: "#app",
            data: {
                message:"hello",
                books:["book1", "book2", "book3", "book4", "book5"]
            },
            components: {
                comp1: {
                    template: comp1,
                    data() {
                        return {
                            books: ["go語言", "java程式設計實戰", "python人工智慧", "php高階開發"]
                        }
                    }
                }
            }
        })
    </script>

直接呼叫模板

<div id="app">
        <p>slot的作用域</p>
        <br>---------------<br>
        <p>原模板展示</p>
        <comp1 ></comp1>
</div>

展示效果:

8.Vue元件三---slot插槽

 

 問題: 這時, 如果我們想要換一種展示方式, 但是展示的資料還是books. 怎麼辦呢?

也就是說, 我們要替換所有的模板內容和樣式, 但是, 模板的資料還是原來的資料.
方法是: 給slot定義一個name, 呼叫的時候指定slot為name的名稱. 並設定當前模板的作用域

第一步: 給模板的插槽定義一個名字

  <template id="comp1">
        <slot :data="books" name="showbooks">
            <div>
                <p>這是一個模板</p>
                <ul>
                    <li v-for="item in books">{{item}}</li>
                </ul>
            </div>
        </slot>
    </template>

第二步: 在替換元件內容的地方定義一個新的template. 指定替換的名字, 並設定作用於為slot

    <p>替換模板的內容: 按照 index - item展示, 並換顏色</p>
        <comp1>
            <template slot-scope="slot" slot="showbooks">
                <ul>
                    <li style="color: cornflowerblue" v-for="(item, index) in slot.data">{{index}} -- {{item}}</li>
                </ul>
            </template>
        </comp1>

在呼叫的時候, 使用slot.data作為資料呼叫.

展示效果:

8.Vue元件三---slot插槽

 

相關文章