SLOT介绍与应用

319 阅读2分钟

什么是slot、插槽的基本使用

slot,即插槽,是为了提高组件复用性而孕育的标签,在组件模板中添加,可以预留位置,用于后续的补充替换,实现一个组件,多个表现样式,极大提升组件的复用性。具体操作如下

 <template id="cnp">
        <div>
        <h2>我是一个组件</h2>
        <p>你全家都是组件</p>
        <slot></slot> 
        </div>
    </template>
    <div id="app">
        <cpn> <button>我是按钮</button> </cpn>
        <cpn> <p>上面的也叫组件</p> </cpn>
        <cpn> <p>上面好像是组件</p> </cpn>
        <cpn> <button>我是按钮</button> </cpn>
    </div>

效果图

当然,slot标签中也可以预设值(即默认值),当你需要改变的时候只需要在外部设置好想要的样式即可自动覆盖

<template id="cnp">
        <div>
        <h2>我是一个组件</h2>
        <p>你全家都是组件</p>
        <slot> <button>我是按钮</button> </slot> 
        </div>
    </template>
    <div id="app">
        <cpn>  </cpn>
        <cpn> <p>上面的也叫组件</p> </cpn>
        <cpn> <p>上面好像是组件</p> </cpn>
        <cpn>  </cpn>
    </div>

效果与上图相同

当然,如果想要插入插槽的部分由若干个小标签组成,则这些标签将会全部嵌入插槽中

具名插槽的使用

当然,一个组件中可以有多个插槽,而为了方便区别各个插槽以及插入插槽的样式,我们使用具名插槽进行解决。

    <template id="cnp">
        <div>
        <slot name="left"> <button>我是第一个的按钮</button></slot>
        <slot name="center"> <button>我是中间的按钮</button></slot>
        <slot name="right"> <button>我是最后的按钮</button> </slot> 
        </div>
    </template>

//在想要插入的部门添加属性slot,并附上要插入的插槽的名字
    <div id="app">
        <cpn> <button slot="center">哈哈</button> </cpn>
    </div>

效果图:

VUE中有一条准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在自己作用域内编译

作用域插槽

作用域插槽主要用于实现 父组件替换插槽的内容,但是内容由子组件来提供

const cpn = {
            template: '#cnp',
            data(){
                return{
                    Languages:['Java','C++','c#','Go']
                }
            }
        }
        const app = new Vue({
            el: "#app",
            data: {

            },
            components: {
                cpn
            },
        }) 
<template id="cnp">
        <div>
            <slot>
                <ul>
                    <li v-for="item in Languages">{{item}}</li>
                </ul>
            </slot>
        </div>
    </template>
    <div id="app">
        <cpn> </cpn>
    </div>

上述例子,如果我想要改变插槽中的样式但是沿用子组件的内容,我们根据作用域可知,不能直接在父组件中写 v-for=”item in Languages”,因为此时的作用域是vue实例app,所以v-for将会在app的data属性中查找 Languages 数组,故此刻我们需要使用作用域插槽,使用v-slot语句实现。v-slot :后边是插槽名称,=后边是组件内部绑定作用域值的映射。

    <template id="cnp">
        <div>
            <slot name='lis' :PLanguages='Languages' :Pid='id'>
                <ul>
                    <li v-for="item in Languages">{{item}}</li>
                </ul>
            </slot>
        </div>
    </template>
    <div id="app">
        <cpn> <button slot="center">哈哈</button> </cpn>
        <cpn v-slot:lis='lang'>
//这里lang是从子组件绑定过来的属性的集合
          <div>{{lang.pid}}</div>
            <div>{{lang.planguages}}</div>
            <span v-for="num in lang.pid">{{num}} </span>
            <!-- object.join('#'):将数组object转化为字符串,并将每个字符间通过#号(可以更换)相连接 -->
            <div>{{lang.planguages.join('*')}}</span></div>
        </cpn>
    </div>
     const cpn = {
            template: '#cnp',
            data(){
                return{
                    Languages:['Java','C++','c#','Go'],
                    id:[12,123,441,234]
                }
            }
        }

需要注意的是,在模板插槽处绑定的属性(这里为PLanguages、Pid),在父组件中应用时字母全部都会变成小写