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


主要內容: 

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>

案例效果

 

四. 插槽的具名

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

可以分兩步:

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

<!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>

 

 

 五. 變量的作用域

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按鈕

 

 

 效果和我們預期的一樣.

總結:

  • 父組件模板的所有東西都會在父級作用域內編譯; 子組件模板的所有東西都會在子級作用域內編譯
  • <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>

展示效果:

 

 問題: 這時, 如果我們想要換一種展示方式, 但是展示的數據還是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作為數據調用.

展示效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM