插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。分为匿名插槽,具名插槽和作用域插槽
1匿名插槽
注册一个组件比如下面的cpn并在父组件中引用,你会看到子组件中有一个slot,这个slot就是插槽,什么意思呢?就是你在父组件中引用子组件的时候,然后在里面加任何东西,你加的东西就是显示的内容,slot标签里面还可以有默认值,当父组件引用子组件时,如果里面不写任何东西,会默认显示slot标签里面的内容
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<cpn>
<h1>123</h1>
</cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<p>我是组件</p>
<p>hahah </p>
<slot></slot>
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data(){
return{}
},
//在vue实例中注册子组件
components:{
cpn:{
template:"#cpn"
}
},
methods: {},
})
</script>
</body>
</html>
2具名插槽
具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。如果使用具名插槽,改变插槽的内容必须先说明要改变哪个插槽
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<cpn>
//只改变了中间插槽的内容
<span slot="center">标题</span>
</cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data(){
return{}
},
//在vue实例中注册子组件
components:{
cpn:{
template:"#cpn"
}
},
methods: {},
})
</script>
</body>
</html>
3作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供
假如现在子组件包括了一组数组,languages:[‘js’,‘c’,‘c#’,‘swift’]
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<cpn>
</cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data(){
return{}
},
//在vue实例中注册子组件
components:{
cpn:{
template:"#cpn",
data(){
return{
languages:['js','c','c#','swift']
}
}
}
},
methods: {},
})
</script>
</body>
</html>
假如现在第一个我想时一个列表,但是第二个我不想用列表的形式展示,我希望以- 分割,这个时候就要用到作用域插槽了,做法就是父组件拿到子组件的数据然后再根据你想要的方式展示数据
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<cpn>
</cpn>
<cpn>
<!-- //这里的slott会引用这个插槽对象 -->
<template slot-scope="slott">
<span v-for="item in slott.data.join('-')">{{item}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<!-- //这里定义一个属性data,名字是随意的,我们要通过名字获取数据,这里的data指向的是language -->
<slot :data="languages">
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script>
var vm = new Vue({
el: "#box",
data(){
return{}
},
//在vue实例中注册子组件
components:{
cpn:{
template:"#cpn",
data(){
return{
languages:['js','c','c#','swift']
}
}
}
},
methods: {},
})
</script>
</body>
</html>