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

主要内容: php

1. 什么是插槽html

2. 组件的插槽vue

3. 插槽的使用方法java

4. 插槽的具名python

5. 变量的做用域编程

6. slot的做用域app


 

一. 什么是插槽呢?

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

usb插槽, 插线板插槽dom

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做为数据调用.

展现效果: