【Vue3 组件封装】vue3 轮播图组件封装
文章目录
- 轮播图功能-获取数据
- 轮播图-通用轮播图组件
- 轮播图-数据渲染
- 轮播图-逻辑封装
轮播图功能-获取数据
目标: 基于pinia获取轮播图数据
核心代码:
(1)在types/data.d.ts文件中定义轮播图数据的类型声明
// 所有接口的通用类型
export type ApiRes <T> = {code: string,msg: string,result: T
}
// 轮播图类型
export type BannerItem = {hrefUrl: stringid: stringimgUrl: stringtype: string
}
(2)在store/home.ts文件中封装接口,用于获取轮播图数据
import { ApiRes, BannerItem } from '@/types/data'
import request from '@/utils/request'
import { defineStore } from 'pinia'export default defineStore('home', {state: () => ({bannerList: [] as BannerItem[],}),actions: {async getBannerList() {const {data: res} = await request.get<ApiRes<BannerItem[]>>('/home/banner')this.bannerList = res.result},},
})
(3)在store/index.ts中导入
import useCategoryStore from './modules/category'
import useHomeStore from './modules/home'
export default function useStore() {return {category: useCategoryStore(),home: useHomeStore(),}
}
(4)通过开发者工具查看数据
<script lang="ts" setup>
import useStore from '@/store'const { home } = useStore()
home.getBannerList()
</script>

轮播图-通用轮播图组件
项目中会多次使用到轮播图组件,但是轮播图渲染的数据是不一样的。
但是轮播图的基本功能都是一样的,比如图片切换,自动播放等等。
因此需要封装一个通用的轮播图组件。
(1)通用轮播图的基本结构src/components/carousel/index.vue
fade 类:用于控制图片的显示和隐藏
active 类:用于控制小圆点高亮
<script lang="ts" setup name="Carousel">
defineProps()
</script><template><div class="carousel"><ul class="carousel-body"><li class="carousel-item fade"><RouterLink to="/"><imgsrc="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"alt=""/></RouterLink></li><li class="carousel-item"><RouterLink to="/"><imgsrc="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"alt=""/></RouterLink></li><li class="carousel-item"><RouterLink to="/"><imgsrc="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"alt=""/></RouterLink></li></ul><a href="javascript:;" class="carousel-btn prev"><i class="iconfont icon-angle-left"></i></a><a href="javascript:;" class="carousel-btn next"><i class="iconfont icon-angle-right"></i></a><div class="carousel-indicator"><span class="active"></span><span></span><span></span><span></span><span></span></div></div>
</template><style scoped lang="less">
.xtxcarousel {width: 100%;height: 100%;min-width: 300px;min-height: 150px;position: relative;.carousel {&-body {width: 100%;height: 100%;}&-item {width: 100%;height: 100%;position: absolute;left: 0;top: 0;opacity: 0;transition: opacity 0.5s linear;&.fade {opacity: 1;z-index: 1;}img {width: 100%;height: 100%;}}&-indicator {position: absolute;left: 0;bottom: 20px;z-index: 2;width: 100%;text-align: center;span {display: inline-block;width: 12px;height: 12px;background: rgba(0, 0, 0, 0.2);border-radius: 50%;cursor: pointer;~ span {margin-left: 12px;}&.active {background: #fff;}}}&-btn {width: 44px;height: 44px;background: rgba(0, 0, 0, 0.2);color: #fff;border-radius: 50%;position: absolute;top: 228px;z-index: 2;text-align: center;line-height: 44px;opacity: 0;transition: all 0.5s;&.prev {left: 20px;}&.next {right: 20px;}}}&:hover {.carousel-btn {opacity: 1;}}
}
</style>
(2)全局注册通用轮播图 src/components/index.ts
import type { App } from 'vue'
import skelecton from './skeleton/index.vue'
+import Carousel from './carousel/index.vue'
export default {install(app: App) {app.component(skelecton.name, skelecton)
+ app.component(Carousel.name, Carousel)},
}
(3)在广告组件中使用src/views/home/components/home-banner.vue
<template><div class="home-banner"><!-- 轮播图 --><Carousel></XtxCarousel></div>
</template>
(4)覆盖样式,控制箭头和小圆点的位置src/views/home/components/home-banner.vue
:deep(.carousel-btn.prev) {left: 270px!important;
}
:deep(.carousel-indicator) {padding-left: 250px;
}
(5)查看效果

轮播图-数据渲染
目的
home-banner组件把数据传递给Carousel组件进行渲染
(1)父传子的方式将数据传给通用轮播图组件src/views/home/components/home-banner.vue
<Carousel :slides="home.bannerList"></Carousel>
(2)子组件接收数据src/components/carousel/index.vue
了解写法:如果通过js的方法定义类型,需要单独引入PropType进行编写
<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
// import { PropType } from 'vue'// defineProps({
// slides: {
// type: Array as PropType<BannerItem[]>,
// required: true,
// },
// })
defineProps<{slides: BannerItem[]
}>()
</script>
(3)渲染轮播图数据src/components/carousel/index.vue
<template><div class="carousel"><ul class="carousel-body"><li class="carousel-item fade" v-for="item in slides" :key="item.id"><RouterLink :to="item.hrefUrl"><img :src="item.imgUrl" alt="" /></RouterLink></li></ul><a href="javascript:;" class="carousel-btn prev"><i class="iconfont icon-angle-left"></i></a><a href="javascript:;" class="carousel-btn next"><i class="iconfont icon-angle-right"></i></a><div class="carousel-indicator"><span v-for="item in slides" :key="item.id" class="active"></span></div></div>
</template>
(4)控制高亮的下标
<script lang="ts" setup name="Carousel">const active = ref(0)
</script>
(5)高亮渲染
- 添加的fade的图片才会展示,所以根据当前索引号进行判断,索引号等于active的才进行展示
- 添加了active类名的小圆点才会高亮,高亮逻辑跟图片一致
<template><div class="carousel"><ul class="carousel-body"><liclass="carousel-item"
+ :class="{ fade: active === index }"
+ v-for="(item, index) in slides":key="item.id"><RouterLink :to="item.hrefUrl"><img :src="item.imgUrl" alt="" /></RouterLink></li></ul><a href="javascript:;" class="carousel-btn prev"><i class="iconfont icon-angle-left"></i></a><a href="javascript:;" class="carousel-btn next"><i class="iconfont icon-angle-right"></i></a><div class="carousel-indicator"><span
+ v-for="(item, index) in slides":key="item.id"
+ :class="{ active: active === index }"></span></div></div>
</template>
轮播图-逻辑封装
实现需求:
- 轮播图里面的图片需要从父组件传入(因为轮播组件可以复用)
- 父组件需要控制轮播图的是否自动播放、动画时间(处理默认值逻辑)
- 是否自动播放和动画时间都是需要默认值的(如果不传就可以使用轮播组件自己提供的默认值)
- 播放逻辑
- 点击小圆点可以切换图片
- 点击prev和next按钮可以播放指定图片(根据图片个数判断播放的循环)
- 如果父组件配置了自动播放,则需要定时播放图片
- 鼠标进入轮播图,暂停轮播
- 鼠标离开轮播图,继续轮播
- 注意点:组件卸载的时候需要清除定时轮播效果(不然组件重新加载的时候会导致多个定时器开启)
(1)父组件传值给轮播图src/views/home/components/home-banner.vue
<template><div class="home-banner"><!-- 轮播图 --><Carousel :slides="slides" autoPlay :duration="3000"></XtxCarousel></div>
</template>
(2)props接收src/components/Carousel.vue
<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
import { ref, PropType } from 'vue'defineProps({slides: {type: Array as PropType<BannerItem[]>,required: true,},autoPlay: {type: Boolean,default: false,},duration: {type: Number,default: 3000,},
})const active = ref(0)
</script>
(3)轮播图的播放逻辑
<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
import { onMounted, onUnmounted, PropType, ref } from 'vue'
// import { PropType } from 'vue'const props = defineProps({slides: {type: Array as PropType<BannerItem[]>,required: true,},duration: {type: Number,default: 3000,},autoPlay: {type: Boolean,default: false,},
})
// const props = defineProps<{
// slides: BannerItem[]
// }>()// 控制高亮
const active = ref(0)const prev = () => {if (active.value <= 0) {active.value = props.slides.length - 1} else {active.value--}
}const next = () => {if (active.value >= props.slides.length - 1) {active.value = 0} else {active.value++}
}const play = () => {// 如果没有自动播放if (!props.autoPlay) return// 在ts中,使用定时器,window.setIntervaltimer = window.setInterval(() => {next()}, props.duration)
}
const stop = () => {clearInterval(timer)
}let timer = -1
// 自动播放
onMounted(() => {play()
})onUnmounted(() => {stop()
})
</script>
(4)鼠标进入和离开操作
<div class="carousel" @mouseenter="stop" @mouseleave="play">
(5)鼠标经过小圆点切换
<spanv-for="(item, index) in slides":key="item.id":class="{ active: active === index }"@mouseenter="active = index"
></span>
(6)点击左右箭头切换
const prev = () => {if (active.value === 0) {active.value = props.slides.length - 1} else {active.value--}
}
const next = () => {if (active.value === props.slides.length - 1) {active.value = 0} else {active.value++}
}// 注册事件
<a href="javascript:;" class="carousel-btn prev" @click="prev"><i class="iconfont icon-angle-left"></i>
</a>
<a href="javascript:;" class="carousel-btn next" @click="next"><i class="iconfont icon-angle-right"></i>
</a>
vascript
const prev = () => {if (active.value === 0) {active.value = props.slides.length - 1} else {active.value--}
}
const next = () => {if (active.value === props.slides.length - 1) {active.value = 0} else {active.value++}
}// 注册事件
<a href="javascript:;" class="carousel-btn prev" @click="prev"><i class="iconfont icon-angle-left"></i>
</a>
<a href="javascript:;" class="carousel-btn next" @click="next"><i class="iconfont icon-angle-right"></i>
</a>
相关文章:
【Vue3 组件封装】vue3 轮播图组件封装
文章目录轮播图功能-获取数据轮播图-通用轮播图组件轮播图-数据渲染轮播图-逻辑封装轮播图功能-获取数据 目标: 基于pinia获取轮播图数据 核心代码: (1)在types/data.d.ts文件中定义轮播图数据的类型声明 // 所有接口的通用类型 export typ…...
电力国家(行业)标准目录
1、3~63kV交流高压负荷开关 GB 3804-90 代替 GB 3804-882、电气装置安装工程35kV及以下架空电力线路施工及验收规范Code for construction and acceptance of 35kVand umder over head power levels electricequipment installation engineeringGB50173—923、带电作…...
如何实现倒序输出
问题 如何实现字符串的大小写转换并倒序输出。 方法 采用Java自带的类方法进行倒序。 package homework4; public class Blog09 { public static void main(String[] args) { String a "HelloWord"; String a2 a.toUpperCase(); String a3 …...
遗留系统的自动化测试策略和实践方法
1 什么是遗留系统 遗留系统是一种旧的方法、旧的技术、旧的计算机系统或应用程序,属于或与以前的、过时的计算机系统有关,但仍在使用中。通常,将系统称为“遗留系统”意味着它可能已经过时或需要更换,但是系统还在对外提供服务,还在不断的迭代,有新的需求不断的交付。Ma…...
【Android】系统源码下载及编译
源码及编译 步骤 1:创建一个空目录来存放源码: mkdir aosp cd aosp步骤 2:获取最新版本的 repo 并签出 android-8.1.0_r1 分支: repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r1其中&am…...
基于HTML实现浪漫情人节表白代码(附源代码)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
PCL 平面拟合——RANSAC
文章目录 一、基本思想二、代码示例1、参数选择2、核心代码3、完整代码4、结果展示三、关于 RANSAC 的一些思考参考文献一、基本思想 随机抽样一致性算法RANSAC(Random sample consensus)是一种迭代的方法,从一系列包含有离群值的数据中计算数学模型参数的方法。RANSAC算法本…...
【Linux之Shell脚本实战】监控系统的磁盘空间使用率
【Linux之Shell脚本实战】监控系统的磁盘空间使用率 一、脚本要求二、检查本地系统环境1.检查系统版本2.检查系统内核版本三、编写disk.sh脚本1.创建脚本目录2.编写disk.sh脚本3.执行测试脚本四、查看脚本执行日志文件五、本次实践总结1.脚本定时执行2.实践总结一、脚本要求 1.…...
【Python安全编程】Python实现网络主机和端口扫描
文章目录前言环境准备Python实现主机扫描基于ARP协议基于ICMP协议普通版本多线程版本Python实现端口扫描扫描单个端口利用多线程扫描端口后记前言 本文主要讲几个利用Python实现网络扫描的小例子,可以结合多线程或多进程编程改进实例 我曾经走过多遥远的路 跨越过多…...
四大垃圾回收算法七大垃圾回收器
JVM的运行时内存也叫做JVM堆,从GC的角度可以将JVM分为新生代、老年代和永久代。其中新生代默认占1/3堆内存空间,老年代默认占2/3堆内存空间,永久代占非常少的对内存空间。新生代又分为Eden区、SurvivorFrom区和SurvivorTo区, Eden…...
P1217 [USACO1.5]回文质数 Prime Palindromes
[USACO1.5]回文质数 Prime Palindromes 题目描述 因为 151151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151151 是回文质数。 写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)[a,b] (5 \le a < b \l…...
用大白话给你科普,到底什么是 API(应用程序编程接口)?
何为API?如果你在百度百科上搜索,你会得到如下结果:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组…...
企业电子招采系统源码——信息数智化招采系统
信息数智化招采系统 服务框架:Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 前端架构:VUE、Uniapp、Layui、Bootstrap、H5、CSS3 涉及技术:Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、…...
【vnc】Ubuntu20.04+vnc安装和配置(中文输入法)
Ubuntu20.04vnc安装和配置(中文输入法) 安装vnc 用以下apt 命令安装: sudo apt install tigervnc-common tigervnc-standalone-server tigervnc-viewer tigervnc-xorg-extension注意,要用standalone-server版本,不要下载Tiger官方安装包&a…...
【排序算法】数据结构排序详解
前言: 今天我们将讲解我们数据结构初阶的最后一部分知识的学习,也是最为“炸裂”的知识---------排序算法的讲解!!!! 目录1.排序的概念及其运用1.1排序的概念1.2排序运用2.常见排序算法的实现2.1 插入排序2…...
【docker知识】DockerFile语法 1:注释指令、解释器指令
一、说明 在docker的指令下工作,似乎很简单,然而,对于复杂工程,这些初级知识是不够的。正确使用DockerFile构建镜像是必须的技能。我们这里假定您已经熟练docker的指令,我们继续上升一个台阶,如何用build和…...
[失业前端恶补算法]JavaScript leetcode刷题top100(一)
专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷 今天更新五个 easy 难度题目: 两数之和 题面 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的…...
HTTP协议
目录 一、HTTP协议 1.http 2.url url的组成: url的保留字符: 3.http协议格式编辑 ①http request ②http response 4.对request做出响应 5.GET与POST方法 ①GET ②POST 7.HTTP常见Header ①Content-Type:: 数据类型(text/html等)在上文…...
javafx学习教程
1.舞台,场景,布局,控件,回调 2.舞台:窗口,一个舞台一个窗口,舞台有舞台基础属性,舞台监听事件,做一些回调 3.fxml里面可以写 页面的布局,控件,然…...
百度百科创建词条教程合集分享,赶紧收藏起来
每一个企业、品牌、人物、产品想要提升自己的知名度,都要创建一个属于自己的百度百科词条,互联网时代,百度搜索引擎的地位是不可撼动的,每天都有上亿的用户在百度上搜索相关内容,百度百科词条在网络营销中占据着举足轻…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
