作用域插槽(作用域插槽传值)

作用域插槽一:假设第一个场景,需要你写一个商品卡片组件,并通过循环去展示多个卡片,并且要求能响应每个卡片上的图片或者其他内容的点击事件而跳转到商品详情页,你会怎么写?我会使用如下的处理方式,首先将商品卡片写成一个组件Commodity.vue,而在CommodityList.vue中用一个v-for来处理商品卡片列表的展示。<commodityv-for=”(item,index)incommodities”@clickCommodity=”onCommodityClick”>&l

大家好,又见面了,我是你们的朋友全栈君。

作用域插槽

一:假设第一个场景,需要你写一个商品卡片组件,并通过循环去展示多个卡片,并且要求能响应每个卡片上的图片或者其他内容的点击事件而跳转到商品详情页,你会怎么写?

我会使用如下的处理方式,首先将商品卡片写成一个组件Commodity.vue,而在CommodityList.vue中用一个v-for来处理商品卡片列表的展示。

<commodity v-for="(item,index) in commodities" @clickCommodity="onCommodityClick"></commodity>

Commodity组件通过$emit像父组件传递clickCommodity事件,并携带商品数据,父组件即可在onCommodityClick方法中得到数据,进行业务处理,这样便完成了一个基本的由子到父的数据传递。

二:如果再往上抽象一下呢?比如我有多个运营栏目,像淘宝首页有“有好货”,“爱逛街”这样两个栏目,每个栏目下都需要有一个商品卡片列表,那么商品卡片列表CommodityList.vue就要抽成组件了。而这个包含多个运营栏目的vue组件我假设它叫ColumnList.vue,在其中通过v-for调用了CommodityList组件。

业务来了,我希望把点击商品卡片的业务放在ColumnList.vue中处理。你们想象一下要怎么做?一种土办法就是商品按钮点击时,Commodity组件 e m i t 通 知 C o m m o d i t y L i s t . v u e , 而 C o m m o d i t y L i s t 接 着 把 事 件 用 emit通知CommodityList.vue,而CommodityList接着把事件用 emitCommodityList.vueCommodityListemit往上抛,那么ColumnList.vue就能处理这个点击事件了。这样做完全没有问题,但是显得子组件很不纯粹,跟业务都扯上关系了。

那么如何优雅地解决这个问题呢?这个时候,作用域插槽真正派上用场了。

通过作用域插槽将本应该由CommodityList处理的商品卡片点击业务onCommodityClick提升到ColumnList处理。

而CommodityList组件内部应该是改造成这样,slot接收来自父组件的商品卡片组件,这里面不涉及关于商品组件的业务,只关注其他业务和布局即可。最终就实现了组件和业务的剥离,这也是组件化的精髓所在吧。不知道有没有帮到您呢?

在这里插入图片描述
1.可以在第一层监听第三层组件的事件,并拿到第三层点击对象的数据
2.数据来源于第一层

第一层 List.vue(ColumnList.vue)

<template>
<el-row :gutter="20">
        <el-col :span="12" v-for="(column, index) in columnList" :key="index">
            <el-card class="box-card card-column">
                <div slot="header" class="clearfix">
                    <span>{ 
   { 
   column.columnName}}</span>
                </div>
                <commodity-list :commodities="column.commodityList">
                    <template slot-scope="scope">
                    <!-- 这里只需要给Commodity组件传入数据,响应Commodity组件的clickCommodity事件即可。
                        事件不必携带参数,完全符合父到子的数据流向,而不会发生子组件又给父组件反向发数据的情况 -->
                        <commodity :modityData="scope.row" @clickcommodity="onCommodityClick(scope.row)"></commodity>
                    </template>
                </commodity-list>
            </el-card>
        </el-col>
</el-row>
</template>

<script>
import commodityList from './commodityList.vue'
import commodity from './commodity.vue'
export default { 
   
  components: { 
   
    commodityList,
    commodity
  },
  data() { 
   
    return { 
   
      columnList: [
        { 
   
          columnName: '爱好货',
          commodityList: [
            { 
   
              id: 1, commodityName: 'iphone1', detail: 'iphone1 iphone1'
            },
            { 
   
              id: 2, commodityName: 'iphone2', detail: 'iphone2 iphone2'
            },
            { 
   
              id: 3, commodityName: 'iphone3', detail: 'iphone3 iphone3'
            }
          ]
        },
        { 
   
          columnName: '爱逛街',
          commodityList: [
            { 
   
              id: 1, commodityName: 'iphone4', detail: 'iphone4 iphone4'
            },
            { 
   
              id: 2, commodityName: 'iphone5', detail: 'iphone5 iphone5'
            },
            { 
   
              id: 3, commodityName: 'iphone6', detail: 'iphone6 iphone6'
            }
          ]
        }
      ]
    }
  },
  methods: { 
   
    onCommodityClick: function(i) { 
   
      console.log(i)
    }
  }
}
</script>

<style lang="less" scoped>
</style>

第二层 commodityList.vue

<template>
  <el-row :gutter="20">
    <el-col :span="8" v-for="(item, index) in commodities" :key="index" style="margin-top:20px;">
      <!-- <span>{ 
   { 
   item}}</span> -->
      <slot :row="item"></slot>
    </el-col>
  </el-row>
</template>

<script>
export default { 
   
  props: { 
   
    commodities: Array
  },
  data() { 
   
    return { 
   
    }
  }
}
</script>

<style lang="less" scoped>
</style>

第三层 commodity.vue

<template>
<div>
  <el-card class="box-card">
    <div slot="header" class="clearfix">
      <span>{ 
   { 
   modityData.commodityName}}</span>
    </div>
    <div>
      <span @click="$emit('clickcommodity')">{ 
   { 
   modityData.detail}}</span>
    </div>
  </el-card>
</div>

</template>

<script>
export default { 
   
  props: { 
   
    modityData: Object
  },
  data() { 
   
    return { 
   
    }
  }
}
</script>

<style lang="less" scoped>
.text { 
   
    font-size: 14px;
  }

  .item { 
   
    margin-bottom: 18px;
  }

  .clearfix:before,
  .clearfix:after { 
   
    display: table;
    content: "";
  }
  .clearfix:after { 
   
    clear: both
  }

  .box-card { 
   
    width: 480px;
  }
</style>

vue卡片拖拽、自动排列交换位置、拖拽数据存取: https://www.cnblogs.com/xiaolucky/p/11699715.html.
vue封装一个卡片组件https://blog.csdn.net/qq_44775782/article/details/104157324.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/129030.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 360 c语言 笔试,奇虎360校招的笔试真题「建议收藏」

    360 c语言 笔试,奇虎360校招的笔试真题「建议收藏」选择题有45个?好像是,三道简答题,简答题:1、设计一个课程表(包括目标人群、核心功能、特色设计);2、说ATM的缺点,改进方法;3、如何让李开复等互联网大牌关注你的微薄?选择题记得不是很清楚,大概是这样的:1、数字推理:1,4,5,6,7,9,11,()2、安卓系统是什么语言开发的?c,c++,java,**3、HTML5不包含的技术?选项有JS、java、*、*4、12个鸡蛋,有一个重量与其他…

    2022年7月14日
    31
  • 【Java基础知识 1】Java入门级概述

    【Java基础知识 1】Java入门级概述1991年成立了一个称为Green的项目小组,帕特里克、詹姆斯·高斯林、麦克·舍林丹和其他几个工程师一起组成的工作小组在加利福尼亚州门洛帕克市沙丘路的一个小工作室里面研究开发新技术,专攻计算机在家电产品上的嵌入式应用。由于C++所具有的优势,该项目组的研究人员首先考虑采用C++来编写程序。但对于硬件资源极其匮乏的单片式系统来说,C++程序过于复杂和庞大。为了解决困难,他们首先着眼于语言的开发,对于新语言的设计,Sun公司研发人员并没有开发一种全新的语言,而是根据嵌入式软件的要求,对C++进行了…

    2022年9月2日
    2
  • paoding分词TokenStream的使用

    paoding分词TokenStream的使用[code="java"]importjava.io.IOException;importjava.io.StringReader;importnet.paoding.analysis.analyzer.PaodingAnalyzer;importorg.apache.lucene.analysis.Analyzer;importorg.apache.lu…

    2022年7月22日
    8
  • Sqoop问题解决:运行报错java.lang.RuntimeException: Could not load db driver class: com.mysql.jdbc.Driver

    Sqoop问题解决:运行报错java.lang.RuntimeException: Could not load db driver class: com.mysql.jdbc.DriverSqoop问题解决:运行报错报错信息:java.lang.RuntimeException:Couldnotloaddbdriverclass:com.mysql.jdbc.Driver原因分析:未将mysql关系型数据库驱动包放到sqoop/lib目录下解决方法:将mysql关系型数据库驱动包放到sqoop/lib目录下这里需要下载mysql关系型数据库驱动包放到本地/opt/software/下mysql依赖包下载链接:https://pan.baidu.com/s

    2022年7月25日
    12
  • 利用Aliddns进行端口映射,外网可以使用域名访问,在公司内网用域名访问不通。

    利用Aliddns进行端口映射,外网可以使用域名访问,在公司内网用域名访问不通。这几天在公司的路由器上做了Aliddns,对公司的内部网络的一些服务映射到公网,在家里就可以访问到公司的一些服务。出现了一个问题:在外网利用域名+端口号可以正常访问到公司的服务,在公司内网的时候访问却没办法利用域名访问,只能用IP才能访问到相关服务找了一些资料,总结原因如下:例:在公司内网访问:访问者:代号A被访问者:代号B路由器:代号R由于在做DDNS时,在路由器上会把B绑定为公网…

    2022年6月6日
    32
  • Django(55)GenericAPIView源码分析

    Django(55)GenericAPIView源码分析源码分析GenericAPIView继承自APIView,也就是在APIView基础上再做了一层封装,源码如下:classGenericAPIView(views.APIView):query

    2022年8月7日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号