领导让小睡做一个小样式,那就用这个小案例作为引入,
看看在不使用插槽的时候、使用插槽时候的区别。下次就知道什么时候使用插槽能更方便了。
看到上面的样式,首先会想到使用组件,然后再App.vue中把标题和内容数据传给子组件即可。
样式的代码没展示,完整代码在最后
<template>
<div class="category">
<h3>{{title}}分类h3>
<ul>
<li v-for="(item,index) in listData" :key="index">{{item}}li>
ul>
div>
template>
<script>
export default {
name:'Category',
//props接收传过来的数据
props:['listData','title']
}
script>
<template>
<div class="container">
<Category title="动漫" :listData="cartoons">Category>
<Category title="游戏" :listData="games"/>
<Category title="电影" :listData="films"/>
div>
template>
<script>
import Category from './components/category.vue'
export default {
name: 'App',
components: {
Category
},
data(){
return{
cartoons:['海贼王','名侦探柯南','一人之下','未闻花名'],
games:['4399','斗地主','王者荣耀','和平精英'],
films:['《你好,李焕英》','《夏洛特烦扰》','《你的名字》','《蜘蛛侠》']
}
}
}
script>
运行之后就是上面的样式了。在上面使用了三次组件,三次组件都是做了同样的展示。
有一天,领导找到小睡,说这个动漫分类和电影分类没有吸引力,你要在动漫分类里加上照片
电影分类里加上电影宣传片。
小睡一听,这还不简单,直接三下五除二在App.vue中改成以下代码。
<Category title="动漫" :listData="cartoons">
<img src="https://img2.baidu.com/it/u=4117582627,679171248&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500" alt="">
Category>
<Category title="游戏" >
Category>
<Category title="电影">
<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">video>
Category>
小睡一运行,才发现动漫分类和电影分类里没有图片和视频。一问旁边的大佬,才知道原因,原来尽管解析了img标签后,需要把img标签加载到组件中去,但是不知道要把img标签放到哪个位置,所以就干脆不放。 为了解决上面的问题,就要使用插槽slot了。
插槽,我理解就是为在组件里挖一个坑的感觉,让组件使用者知道可以把一些标签填充在里面。
[补充]:可以在组件或App.vue中给img标签编写样式
因为解析了img标签后,把img标签填入组件中所以可以在组件或App.vue中给img标签编写样式
后来小睡将代码改成如下
<template>
<div class="category">
<h3>{{title}}分类h3>
<slot>这里可以填写默认值,当组件使用者没有进行填充时,会显示slot>
div>
template>
<script>
export default {
name:'Category',
props:['title']
}
script>
<template>
<div class="container">
<Category title="动漫" :listData="cartoons">
<img src="https://img2.baidu.com/it/u=4117582627,679171248&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500" alt="">
Category>
<Category title="游戏" >
<ul>
<li v-for="(g,index) in games" :key="index">{{g}}li>
ul>
Category>
<Category title="电影">
<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">video>
Category>
div>
template>
<script>
import Category from './components/category.vue'
export default {
name: 'App',
components: {
Category
},
data(){
return{
games:['4399','斗地主','王者荣耀','和平精英']
}
}
}
script>
领导看了小睡的样式之后,又对小睡说,你再在每一个分类栏下面加上几个超链接
小睡听完,觉得很简单,说直接在App.vue中的组将使用中分别填充几个超链接不就行了
旁边的大佬说:"小睡,你可以试试--具名插槽"
当我们需要多个插槽时,对于这种情况,< slot > 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽。在我们前面插槽都没有使用name属性,它带有一个隐含的名字:default。即< slot > slot >等价于< slot name=“default”> slot >
组件中定义具名插槽
<slot name="center">这里可以填写默认值,当组件使用者没有进行填充时,center会显示slot>
使用具名插槽
需要使用< template > template >包裹住填充的内容
<template v-slot:center>
template>
代码
<template>
<div class="category">
<h3>{{title}}分类h3>
<slot name="center">这里可以填写默认值,当组件使用者没有进行填充时,center会显示slot>
<slot name="foot">这里可以填写默认值,当组件使用者没有进行填充时,foot会显示slot>
div>
template>
<script>
export default {
name:'Category',
props:['title']
}
script>
<template>
<div class="container">
<Category title="动漫" :listData="cartoons">
<template v-slot:center>
<img src="https://img2.baidu.com/it/u=4117582627,679171248&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500" alt="">
template>
<template v-slot:foot>
<a href="https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%B6%AF%C2%FE%CD%BC%C6%AC&fr=ala&ala=1&alatpl=normal&pos=0">更多照片a>
template>
Category>
<Category title="游戏" >
<template v-slot:center>
<ul>
<li v-for="(g,index) in games" :key="index">{{g}}li>
ul>
template>
<template v-slot:foot>
<div class="footer">
<a href="https://www.csdn.net/">手机游戏a>
<a href="https://www.csdn.net/">电脑游戏a>
div>
template>
Category>
<Category title="电影">
<template v-slot:center>
<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">video>
template>
<template v-slot:foot>
<div class="footer">
<a href="https://www.csdn.net/">经典a>
<a href="https://www.csdn.net/">热门a>
<a href="https://www.csdn.net/">推荐a>
div>
template>
Category>
div>
template>
这天,小睡遇到一个问题,当数据在子组件中,需要让插槽填充的内容可以访问到。
这个需要使用作用域插槽了。
举个例子,游戏分类中的数据在子组件中,但是需要用不同的渲染方式展现出来,第一个是无序,第二个是有序的,第三个是用< h4 >来展示
子组件传数据给插槽填充内容
//子组件中的数据
data(){
return{
games:['4399','斗地主','王者荣耀','和平精英']
}
}
<slot :games="games">slot>
上面的代码片段都是在子组件中。
填充内容接收数据
<template v-slot:default="obj">
{{obj}}
template>
接收的数据:{“games”:[‘4399’,‘斗地主’,‘王者荣耀’,‘和平精英’]}
注意:
1、v-slot:default=“obj”,"obj"可以写成任意字符串,
2、接收的是一个json对象,要获取数组数据可以obj.games获取
3、v-slot:default=“obj” 的写法是默认插槽的写法,默认插槽有简便写法v-slot=“obj”
4、还可以解构插槽。 什么是解构赋值
5、一个元素不能有多个 ‘< template>’ 元素分布在同一个槽中。
组件代码
<template>
<div class="category">
<h3>{{title}}分类h3>
<slot :games="games">默认插槽slot>
div>
template>
<script>
export default {
name:'Category',
props:['title'],
data(){
return{
games:['4399','斗地主','王者荣耀','和平精英']
}
}
}
script>
App.vue代码
<template>
<div class="container">
<Category title="游戏">
<template v-slot:default="obj">
<ul>
<li v-for="(g,index) in obj.games" :key="index">{{g}}li>
ul>
template>
Category>
<Category title="游戏">
<template v-slot="obj">
<ol>
<li v-for="(g,index) in obj.games" :key="index">{{g}}li>
ol>
template>
Category>
<Category title="游戏">
<template v-slot="{games}">
<h4 v-for="(g,index) in games" :key="index">{{g}}h4>
template>
Category>
div>
template>
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:
使用
<template v-slot:[dynamicSlotName]>
template>
组件代码
<template>
<div class="category">
<h3>{{title}}分类h3>
<slot name="1" :games="games1">slot>
<slot name="2" :games="games2">slot>
div>
template>
<script>
export default {
name:'Category',
props:['title'],
data(){
return{
games1:['4399','斗地主','王者荣耀','和平精英'],
games2:['我的世界','cf','LOL','cs']
}
}
}
script>
App.vue代码
<template>
<div class="container">
<Category title="游戏">
<template v-slot:[dynamicSlotName]="obj">
<ol>
<li v-for="(g,index) in obj.games" :key="index">{{g}}li>
ol>
template>
Category>
<button style="width:120px" @click="change">点这切换button>
div>
template>
<script>
import Category from './components/category.vue'
export default {
name: 'App',
components: {
Category
},
data(){
return{
dynamicSlotName:'1'
}
},
methods:{
change(){
if(this.dynamicSlotName=='1'){
this.dynamicSlotName='2';
}else
this.dynamicSlotName='1';
}
}
}
script>
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #
<template #center>
template>
代码
推荐一个加速软件——DivSidecar
意为为开发者打辅助的边车工具,通过本地代理的方式将https请求代理到一些国内的加速通道上
1、GitHub打不开,加速Github 很有用。
2、 dns优选(解决污染问题)
3、Stack Overflow 加速
4、 npm加速