1.slot意思为插槽,简单地理解,插槽可以理解为其为我们预留了一块空间,我们想插入什么东西就插入什么东西,比如一个app,很多界面都用到了导航栏或者tabbar这种东西,然而每一个界面的导航栏显示的东西内容又不一样,但其实这些都可以用插槽来实现,定义好插槽,使用者插入自己想要的内容再使用即可
2.插槽的基本使用,首先是基于2.6.0以下的
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content">
<!--如果我们单纯啥都不传,而且插槽有默认的内容的话就显示默认内容-->
<mycom></mycom>
<!--如果我们传入内容,内容会覆盖到插槽的内容-->
<mycom>
<h2>胡来可不行</h2>
</mycom>
</div>
<template id="mytemp">
<div>
<!--子组件里定义一个插槽-->
<slot>插槽的默认内容</slot>
<h2>子组件的内容</h2>
</div>
</template>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#content',
components: {
'mycom': {
template: '#mytemp'
}
}
})
</script>
</body>
</html>
结果
3.具名插槽,当如果一个组件里面存在多个插槽时,我们想要指定某一个插槽插入指定内容时,就可以使用具名插槽了。
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content">
<!--啥都不传,默认会显示插槽的默认内容-->
<mycom></mycom>
<!--只传一个home,其他的会默认显示-->
<mycom>
<span slot="home">首页</span>
</mycom>
<!--全都传-->
<mycom>
<span slot="home">首页</span>
<span slot="category">分类</span>
<span slot="cart">购物车</span>
<span slot="myself">我的</span>
</mycom>
</div>
<template id="mytemp">
<div>
<slot name="home">home</slot>
<slot name="category">category</slot>
<slot name="cart">cart</slot>
<slot name="myself">myself</slot>
</div>
</template>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#content',
components: {
'mycom': {
template: '#mytemp'
}
}
})
</script>
</body>
</html>
结果
4.作用域插槽,作用域可以理解为,一个组件只可以使用自己的数据,直接引用其他的组件的数据会报错,除非通过父子组件通信的方式来实现数据的传递,那我们在使用插槽时,可能想要达到一种效果就是在父组件里引入子组件的数据
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content">
<mycom>
<!--结合template标签,拿到子组件里的内容-->
<template slot-scope="slotData">
<ul>
<li v-for="item in slotData.message">{{item}}</li>
</ul>
</template>
</mycom>
</div>
<template id="mytemp">
<div>
<!--给插槽绑定一个属性message,并且值为fruits-->
<slot :message="fruits"></slot>
</div>
</template>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#content',
//注册一个组件
components: {
'mycom': {
template: '#mytemp',
data() {
return {
fruits: ['banana','apple','grape','peach','cherry']
}
}
}
}
})
</script>
</body>
</html>
结果
分析
6.注意2.6.0.版本开始,slot-scope已被废弃,我们可以使用v-slot
以下为2.6.0后插槽的使用:
1)具名插槽的使用
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content">
<mycom>
<!--结合template标签,拿到子组件里的内容-->
<template v-slot:header>
<h2>我是头部内容</h2>
</template>
<!--v-slot后面默认是加了:default即是v-slot:default,会找到没有name属性的插槽,并且把当前内容插入进去-->
<template v-slot>
<h2>我是主要内容</h2>
</template>
<template v-slot:footer>
<h2>我是尾部内容</h2>
</template>
</mycom>
</div>
<template id="mytemp">
<div>
<!--子组件里定义三个个插槽-->
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#content',
components: {
'mycom': {
template: '#mytemp'
}
}
})
</script>
</body>
</html>
结果
分析
2)作用域插槽,这里对于具名插槽有个语法糖写法,v-slot:footer,可以写成#footer,注意:默认的插槽和具名插槽不能混合使用,使用的话,有些内容不会显示,以下有例子示范
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content">
<mycom>
<!--v-slot相当于v-slot:default-->
<template v-slot="defaultdata">
<h2 v-for="item in defaultdata.movies">{{item}}</h2>
</template>
<template v-slot:footer="slotdata">
<h2 v-for="item in slotdata.books">{{item}}</h2>
</template>
</mycom>
<!--具名插槽和默认插槽不能嵌套使用,以下就是错误的写法,我们会发现,具名插槽的内容不会显示出来-->
<mycom>
<!--v-slot相当于v-slot:default-->
<template v-slot="defaultdata">
<h2 v-for="item in defaultdata.movies">{{item}}</h2>
<template v-slot:footer="slotdata">
<h2 v-for="item in slotdata.books">{{item}}</h2>
</template>
</template>
</mycom>
</div>
<template id="mytemp">
<div>
<!--子组件里定义三个个插槽-->
<slot name="header"></slot>
<slot v-bind:movies="movies"></slot>
<slot name="footer" v-bind:books="books"></slot>
</div>
</template>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#content',
components: {
'mycom': {
template: '#mytemp',
data(){
return {
books: ['java','c#','c++','javascript','python','go'],
movies: ['海贼王','火影','离殇']
}
}
}
}
})
</script>
</body>
</html>
结果
分析