• Vue——插槽


    引例

    想要实现如下效果:
    在这里插入图片描述
    发现3个模块的样式一样,所以可以写一个组件,传递不同的数据实现。
    实现代码:
    单个样式:Category组件(子组件)
    Category.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: 'CategoryVue',
        props:['listData','title']
    }
    script>
    
    <style>
    .category{
        width:200px;
        height: 300px;
        background: lightseagreen;
    }
    h3{
        text-align: center;
    background: lightgoldenrodyellow;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    App.vue:

    <template>
      <div class="container">
        <Category title="美食" :listData="foods"/>
        <Category title="游戏" :listData="games"/>
        <Category title="电影" :listData="films"/>
      div>
    template>
    
    <script>
    import Category from "@/components/Category";
    export default {
      name: "App",
      data() {
        return {
          foods: ['烧烤', '火锅', '小龙虾', '螺蛳粉'],
          films: ['《当幸福来敲门》', '《泰坦尼克号》', '《阿甘正传》', '《海上钢琴师》'],
          games:['王者荣耀','我的世界','和平精英','穿越火线']
        }
      },
      components: {
        Category
      }
    }
    script>
    <style lang="css">
    .container{
      display: flex;
      justify-content: space-around;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    那如果想要实现如下效果又该怎么做呢?
    (即不同的模块显示的内容格式不一样)——可以通过插槽来实现
    在这里插入图片描述

    普通插槽

    插槽标签:

    使用方法

    • 插槽一般定义在子组件中,相当于一个占位。
    • 父组件模板中的子组件标签要写成一对的样式,即:
    • 这样中的内容就会显示在子组件标签的位置。
    • 如果中没有内容,标签中的内容就会显示在页面。

    这里父组件被称为插槽的使用者

    实现:
    Category.vue:

    <template>
        <div class="category">
            <h3>{{title}}h3>
            
            <slot>我是一个插槽,如果组件标签中没有传递值时,我就显示,否则显示组件传递过来的内容slot>
        div>
    template>
    
    <script>
    export default {
        name: 'CategoryVue',
        props:['listData','title']
    }
    script>
    
    <style>
    
    .category{
        width:200px;
        height: 300px;
        background: lightseagreen;
        overflow: hidden;
    }
    h3{
        text-align: center;
    background: lightgoldenrodyellow;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    App.vue

    <template>
      <div class="container">
        <Category title="美食">
          <img src="./assets/1.jpg" />
        Category>
        <Category title="游戏">
          <ul>
            <li v-for="(game,index) in games" :key="index">{{game}}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";
    export default {
      name: "App",
      data() {
        return {
          foods: ['烧烤', '火锅', '小龙虾', '螺蛳粉'],
          films: ['《当幸福来敲门》', '《泰坦尼克号》', '《阿甘正传》', '《海上钢琴师》'],
          games:['王者荣耀','我的世界','和平精英','穿越火线']
        }
      },
      components: {
        Category
      }
    }
    script>
    <style lang="css">
    .container{
      display: flex;
      justify-content: space-around;
    }
    img{
      width: 100%;
    }
    video{
      width: 100%;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    实现效果:
    在这里插入图片描述
    如果App.vue的子组件标签中不放内容,就会将是如下样式:(将slot的内容进行显示)
    在这里插入图片描述

    插槽的编译

    app.vue子组件标签中的html代码片段是编译完之后再放到子组件的插槽中去,所以该html代码片段的样式既可以卸载app.vue文件中,也可以写在子组件中。

    具名插槽

    一个子组件可能有多个插槽,不同的插槽放置不同的内容,为了区分不同的插槽,每个插槽应该有自己的名字,这就是具名插槽

    同时app.vue子组件标签中的html代码片段的内容也需要设置slot属性,用于指明该片段放在哪个插槽中。
    如果两个片段放在一个插槽中,不会覆盖只是追加。

    category.vue(子组件)

    <template>
        <div class="category">
            <h3>{{title}}h3>
            
            <slot name="center">我是一个插槽,如果组件标签中没有传递值时,我就显示,否则显示组件传递过来的内容centerslot>
            <slot name="footer">我是一个插槽,如果组件标签中没有传递值时,我就显示,否则显示组件传递过来的内容footerslot>
        div>
    template>
    
    <script>
    export default {
        name: 'CategoryVue',
        props:['listData','title']
    }
    script>
    
    <style>
    
    .category{
        width:200px;
        height: 300px;
        background: lightseagreen;
        overflow: hidden;
    }
    h3{
        text-align: center;
    background: lightgoldenrodyellow;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    app.vue(父组件)

    <template>
      <div class="container">
        <Category title="美食">
          <img slot="center" href="./assets/1.jpg" />
          <a slot="footer" href="https://www.baidu.com">点我查看更多a>
        Category>
        <Category title="游戏">
          <ul slot="center">
            <li v-for="(game,index) in games" :key="index">{{game}}li>
          ul>
          <a slot="footer" href="https://www.baidu.com">单机游戏a>
          <a slot="footer" href="https://www.baidu.com">网络游戏a>
        Category>
        <Category title="电影">
          <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">video>
          <div class="foot" slot="footer">
            <a href="https://www.baidu.com">经典a>
            <a href="https://www.baidu.com">热门a>
            <a href="https://www.baidu.com">推荐a>
          div>
        Category>
      div>
    template>
    
    <script>
    import Category from "@/components/Category";
    export default {
      name: "App",
      data() {
        return {
          foods: ['烧烤', '火锅', '小龙虾', '螺蛳粉'],
          films: ['《当幸福来敲门》', '《泰坦尼克号》', '《阿甘正传》', '《海上钢琴师》'],
          games:['王者荣耀','我的世界','和平精英','穿越火线']
        }
      },
      components: {
        Category
      }
    }
    script>
    <style lang="css">
    .container,.foot{
      display: flex;
      justify-content: space-around;
    }
    img{
      width: 100%;
        height: 50%;
    }
    video{
      width: 100%;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    效果:
    在这里插入图片描述

    template

    slot属性碰上template标签可以这样写:

    eg:

          <template v-slot:footer>
            <div class="foot">
              <a href="https://www.baidu.com">经典a>
              <a href="https://www.baidu.com">热门a>
              <a href="https://www.baidu.com">推荐a>
            div>
            <h4>欢迎观看电影h4>
          template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    作用域插槽

    作用域插槽的应用场景:
    数据子组件中,而根据数据生成的结构插槽的使用者上。
    (插槽的使用者即使用子组件的父组件)。

    传递数据
    因为插槽的使用者(父组件)需要使用子组件的数据, 所以需要将数据从子组件传递到插槽的使用者中。

    • 子组件的传递方法,利用插槽标签结合v-bind指令进行传递:

      可以传递多个数据
    • 插槽的使用者接收的方法:使用标签的scope属性接收从子组件通过标签传递过来的所有数据,接收到的数据是一个对象。
      也可以使用标签的slot-scope属性接收数据。
      scope和slot-scope接收数据支持解构赋值
    <template scope="自己起的变量名">
    template>
    
    • 1
    • 2

    使用:

    • 子组件category.vue —— 数据在子组件中
    <template>
        <div class="category">
            <h3>{{title}}h3>
            
            
            <slot :games="games">我是一个插槽slot>
        div>
    template>
    
    <script>
    export default {
        name: 'CategoryVue',
        props: ['title'],
        data() {
            return{
                games: ['王者荣耀', '我的世界', '和平精英', '穿越火线']
            }
        }
    }
    script>
    
    <style>
    
    .category{
        width:200px;
        height: 300px;
        background: lightseagreen;
        overflow: hidden;
    }
    h3{
        text-align: center;
    background: lightgoldenrodyellow;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 父组件App.vue(插槽的使用者) —— 结构在父组件中
    <template>
      <div class="container">
        <Category title="游戏">
          
          
          <template scope="youxi">
            <ul>
              <li v-for="(game,index) in youxi.games" :key="index">{{game}}li>
            ul>
          template>
        Category>
        <Category title="游戏">
          
          <template scope="{games}">
            <ol>
              <li v-for="(game,index) in games" :key="index">{{game}}li>
            ol>
          template>
        Category>
        <Category title="游戏">
          
          <template slot-scope="{games}">
            <h4 v-for="(game,index) in games" :key="index">{{game}}h4>
          template>
        Category>
      div>
    template>
    
    <script>
    import Category from "@/components/Category";
    export default {
      name: "App",
      components: {
        Category
      }
    }
    script>
    <style lang="css">
    .container{
      display: flex;
      justify-content: space-around;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    实现的效果:
    在这里插入图片描述
    作用域插槽可以设置名字

    插槽总结

    • 插槽的作用:
      让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于父组件===>子组件
  • 相关阅读:
    软件专业毕业生的如何找工作?——加速度jsudo
    这家提供数据闭环完整链路的企业,已拿下多家头部主机厂定点
    富格林:总结阻挠欺诈解决措施
    cnpm的版本锁定问题的解决方案
    一文看懂博睿数据银行解决方案
    js性能-对象查找值与迭代查找值性能对比
    UWB学习——day5
    Wespeaker框架数据集准备(1)
    深度解析单例模式
    Dubbo-Dubbo 动态配置中心
  • 原文地址:https://blog.csdn.net/mantou_riji/article/details/125918153