什么是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),在父组件中应用时字母全部都会变成小写