【Vue】Re07 插槽Slot

一、插槽基本使用

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

<!--
    slot的使用目的是对组件中设置一个空白的自定义元素位置
    在实际Vue实例中使用组件时,每一个调用的组件在定义的位置中插入不同的元素
-->
<div id="aaa">
    <comp>
        <!-- 2、在使用中插入我们希望的东西 -->
        <button>这是我们插入的按钮</button>
    </comp>

    <comp>
        <p>这是我们插入的段落</p>
    </comp>
    
    <comp>
        <span>插入我们自定义的内容</span>
    </comp>
</div>

<template id="sss">
    <div>
        <h3>我是组件</h3>
        <p>我是内容</p>
        <slot></slot> <!-- 1、在组件的模板中定义插槽标签 -->
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    const v = new Vue({
        el : '#aaa',
        components : {
            comp : {
                template : '#sss'
            }
        }
    });
</script>
</body>
</html>

二、具名插槽的使用

具名插槽,意思就是插槽标签具备name属性,可以命名插槽:

要注意的是,不要和普通slot元素混用,造成插槽混乱

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

<div id="app">
    <cpn>
        <span slot="right">替换name属性为right的插槽</span>
    </cpn> <!-- 如果插入的元素没有指定,默认替换掉没有name属性的 -->

    <hr>

    <cpn>
        <span slot="center">替换name属性为center中间的插槽</span> <!-- 或者指定具体名称进行插入 -->
    </cpn>
</div>

<template id="cpn">
    <div>
        <h3>组件</h3>
        <p>内容</p>

        <p>
            <!-- 具名插槽 slot标签具有名字属性  -->
            <slot  name="left"><span>左边</span></slot>
            <slot  name="center"><span>中间</span></slot>
            <slot  name="right"><span>右边</span></slot>
        </p>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    const v = new Vue({
        el : '#app' ,
        components : {
            cpn : {
                template : '#cpn'
            }
        },
    });
</script>
</body>
</html>

三、编译作用域问题:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 编译作用域 -->
<div id="app">
    <cpn v-show="isShow"></cpn> <!-- 3、判断组件是否显示  -->
</div>
<!-- 答案是true原因是因为 在实例容器元素中只会渲染实例的属性变量,只有在组件自己的实例中去调用自己的属性变量 -->

<template id="sss">
    <div>
        <h3>ssss</h3>
        <p>
            不显示的按钮
            <button v-show="isShow">不显示的按钮</button>
        </p>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    const app = new Vue({
        el : '#app',
        data : {
            message : '你好',
            isShow : true /* 1、 在Vue实例中提供了一个属性isShow 值为true */
        },
        components : {
            cpn : {
                template: '#sss',
                data () {
                    return {
                        isShow : false /* 2、 在注册的组件实例中提供了一个属性isShow 值为false */
                    }
                },
            },
        },
    })
</script>
</body>
</html>

四、作用域插槽:

在父组件中替换插槽的标签元素,但是值内容由子组件提供

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

<div id="aaa">
<!--    <comp></comp>-->
<!--    <comp></comp>-->
<!--    <comp></comp>-->
    <comp>
        <template slot-scope="slot">
            <!--<span v-for="item in slot.data">{{item}} | </span>-->
            
            <!-- 解决拼接符号的问题 -->  <span>{{slot.data.join(' | ')}}</span>
        </template> <!-- template 用data获取 也可以把绑定的属性用其他命名 -->
    </comp>
</div>

<!--<template id="sss">-->
<!--    <div>-->
<!--        <ul>-->
<!--            <li v-for="pl in programLanguages">{{pl}}</li>-->
<!--        </ul>-->
<!--    </div>-->
<!--</template>-->

<template id="sss">
    <div>
        <slot :data="programLanguages"> <!-- 把一个data属性绑定到这个pl变量 -->
            <ul>
                <li v-for="pl in programLanguages">{{pl}}</li>
            </ul>
        </slot>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    const aaa = new Vue({
        el : '#aaa',
        components : {
            comp : {
                template : '#sss',
                data () {
                    return {
                        programLanguages : [
                            'JavaScript',
                            'C/C++',
                            'ObjectiveC',
                            'VisualBasic',
                            'Java',
                            'GoLang',
                            'Swift',
                            'Python',
                            'Ruby',
                            'Rust',
                            'PHP'
                        ]
                    }
                }
            }
        }
    })
</script>
</body>
</html>

 

posted @ 2020-10-29 09:43  emdzz  阅读(350)  评论(0编辑  收藏  举报