Vue中v-slot、插槽详解(看完这篇插槽对你来说很简单)

目录

  • 不使用插槽
  • 默认插槽
  • 具名插槽
  • 作用域插槽
  • 动态插槽名
  • 和具名插槽的缩写
  • 完整代码

不使用插槽

领导让小睡做一个小样式,那就用这个小案例作为引入,
看看在不使用插槽的时候、使用插槽时候的区别。下次就知道什么时候使用插槽能更方便了。

Vue中v-slot、插槽详解(看完这篇插槽对你来说很简单)_第1张图片
看到上面的样式,首先会想到使用组件,然后再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>

运行之后就是上面的样式了。在上面使用了三次组件,三次组件都是做了同样的展示。

默认插槽

有一天,领导找到小睡,说这个动漫分类和电影分类没有吸引力,你要在动漫分类里加上照片
电影分类里加上电影宣传片。

Vue中v-slot、插槽详解(看完这篇插槽对你来说很简单)_第2张图片

小睡一听,这还不简单,直接三下五除二在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中的组将使用中分别填充几个超链接不就行了
旁边的大佬说:"小睡,你可以试试--具名插槽"

Vue中v-slot、插槽详解(看完这篇插槽对你来说很简单)_第3张图片
当我们需要多个插槽时,对于这种情况,< slot > 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽。在我们前面插槽都没有使用name属性,它带有一个隐含的名字:default。即< slot >等价于< slot name=“default”>

组件中定义具名插槽

 <slot name="center">这里可以填写默认值,当组件使用者没有进行填充时,center会显示slot>

使用具名插槽
需要使用< 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 >来展示
Vue中v-slot、插槽详解(看完这篇插槽对你来说很简单)_第4张图片
子组件传数据给插槽填充内容

//子组件中的数据
 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加速

你可能感兴趣的:(vue开发问题,vue.js,javascript)