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

作用域插槽一:假设第一个场景,需要你写一个商品卡片组件,并通过循环去展示多个卡片,并且要求能响应每个卡片上的图片或者其他内容的点击事件而跳转到商品详情页,你会怎么写?我会使用如下的处理方式,首先将商品卡片写成一个组件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.

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • python 中进制转换及format(),int()函数用法「建议收藏」

    python 中进制转换及format(),int()函数用法「建议收藏」python中数值型变量好像只能是十进制形式表示,其他类型变量只能以字符串形式存在,可以通过format函数将int类型变量转换成其他进制字符串,如下所示:其中,通过格式符#决定是否显示前置符号,通

  • 【mysql】细说 数据库隔离级别 及实现

    【mysql】细说 数据库隔离级别 及实现网上大多数关于隔离级别的文章都是讲了事务中的问题以及隔离级别可以解决的问题,我这次想看看数据库底层是如何实现隔离级别的。不过还是先来回顾一下隔离级别以及可能发生的问题。1.脏读:指的是一个事务的读操作读到了另一个未提交的事务修改的值。比如下面的场景:脏读的问题是,读到的值可能会被回滚,那么这个值就是失效的,不能继续使用,否则会有一致性问题。2.不可重复读:指的是一个事务读…

  • 阿里云服务器开放80端口「建议收藏」

    阿里云服务器开放80端口「建议收藏」阿里云服务器开放80端口1.先登录阿里云官网https://www.aliyun.com/2.点击控制台3.点击左边的三条杆4.点击进去之后,找到云服务器ECS5.点击蓝色字体的服务器名称6.找到安全组,安全组列表,加入安全组,配置规则7.点击入方向里的手动添加8.设置如下图所示的参数,最后记得保存哦9.至此,80端口就设置好了。因为我这里设置了Nginx,所以80端口会被占用10.我们在浏览器上访问,也可以验证成功…

  • 人工智能AI:TensorFlow Keras PyTorch MXNet PaddlePaddle 深度学习实战 part1

    人工智能AI:TensorFlow Keras PyTorch MXNet PaddlePaddle 深度学习实战 part1日萌社github标星11600+:最全的吴恩达机器学习课程资源(完整笔记、中英文字幕视频、python作业,提供百度云镜像!)KerasPyTorchMXNetTensorFlowPaddlePaddle深度学习实战用户画像C、C++笔记JavaWeb+大数据笔记CDH6、CDH5Python笔记链接:https://pan.baidu.com/s/1…

  • ASP Session 对象

    ASP Session 对象Session对象用于存储关于某个用户会话(session)的信息,或者修改相关的设置。存储在session对象中的变量掌握着单一用户的信息,同时这些信息对于页面中的所有页面都是可用的。实例设置并返回LCID本例演示”LCID”属性。此属性设置并返回一个指明位置或者地区的整数。类似于日期、时间以及货币等内容都要根据位置或者地区来显示。返回SessionID本例演示”Ses

  • vue页面刷新_vue强制重置组件

    vue页面刷新_vue强制重置组件vue页面刷新首先我们都知道vue属于单页面应用,默认境况下是不会触发刷新页面操作的,所以这个时候就需要我们通过事件来触发reload()来达到刷新操作接下来我就为大家介绍三种刷新页面的方法1.wiindow.location.reload([bForceGet])该方法强迫浏览器刷新当前页面bForceGet可选参数,默认为false,从客户端缓存里取当前true,则以get方式,从服务器端获取最新的页面,相当于页面f5刷新wiindow.location.replace(URL)

    2022年10月16日

发表回复

您的电子邮箱地址不会被公开。

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