二次封装el-carousel

我们创建了一个名为MyCarousel的组件,它接受el-carousel的一些常用属性作为props,并默认提供了一些值。我们还通过setup函数返回了所有props,以便它们可以在模板中被使用。

1.MyCarousel.vue组件

<!-- 轮播图片 -->
<template>
	<div class="carousel" :class="[{ twoBox: isTwo }, { elseBox: !isTwo }]">
		<el-carousel
			loop
			indicator-position="outside"
			class="carouselBox"
			:arrow="carouselListData.length === 1 ? 'never' : 'hover'"
			@change="changeItem"
			ref="carouse"
		>
			<el-carousel-item
				:width="props.width + 'px'"
				v-for="(item, index) in carouselListData"
				:key="index"
				@click="goHomepage(item)"
			>
				<img
					:src="item.imageUrl"
					:style="{
						width: props.widthImage + '%',
						height: props.heightImage + '%',
						cursor: item.posterLink || props.activeTab ? 'pointer' : ''
					}"
					alt="轮播图图片"
				/>
			</el-carousel-item>
		</el-carousel>
	</div>
</template>

<!-- 轮播图 -->
<script setup lang="ts" name="CustomCarousel">
	import { QueryPosterInfoListOutput } from '@/api/home/types';
	import _ from 'lodash';

	const isTwo = ref(false); // 判断是不是两条数据
	const carouse = ref();
	const emit = defineEmits({ clickGoPage: null, changeItem: null });
	const props = defineProps({
		// 轮播图宽度
		width: {
			type: Number,
			default: 0
		},
		// 轮播图高度
		height: {
			type: String,
			default: '400'
		},
		type: {
			type: String,
			default: 'card'
		},
		// 相邻两张图片切换的间隔时间
		interval: {
			type: Number,
			default: 4000
		},
		//图片宽
		widthImage: {
			type: Number,
			default: 100
		},
		//图片高
		heightImage: {
			type: Number,
			default: 100
		},
		// 轮播图路径数组
		carouselList: {
			type: Array<QueryPosterInfoListOutput>,
			default: () => []
		},
        // 点击不同的tab切换对应的轮播图
		activeTab: {
			type: Number,
			default: 0
		}
	});
	const activeIndex = ref(0);
	const carouselListData = ref<QueryPosterInfoListOutput[]>([]);

	watch(
		() => props.carouselList,
		(newVal) => {
			fu(newVal);
		}
	);
	// 针对阶梯套餐的特殊处理
	watch(
		() => props.activeTab,
		(newVal) => {
			// console.log(activeIndex.value, 'newVal======', newVal);
			// 因为是element-ui组件的一个bug两张图片的需要单独特殊处理,目的是避免切换tab的时候,轮播图切换到上一张,轮播方向错误
			if (isTwo.value) {
				// 上一个的tab值
				const prev = carouselListData.value[activeIndex.value];
				// 如果上一个的值和当前点击的的一样,不做改变
				if (prev.id === newVal) {
					return;
				} else {
					let index = _.findIndex(carouselListData.value, (item, i) => {
						return item.id === newVal && i > activeIndex.value;
					});
					// 如果是最后一张图的时候需要回来到第一张图片
					if (index === -1) {
						index = 0;
					}
					// 重新设置选中的默认值
					carouse.value.setActiveItem(index);
				}
			} else {
				const index = _.findIndex(carouselListData.value, (item) => {
					return item.id === newVal;
				});
				carouse.value.setActiveItem(index);
			}
		}
	);

	// 点击进入链接,发起方法调用
	const goHomepage = (value: QueryPosterInfoListOutput) => {
		emit('clickGoPage', value);
		if (value.posterLink) {
			window.open(value.posterLink, '_blank');
		}
	};
    
	const changeItem = (val: any) => {
		const value = carouselListData.value[val];
		activeIndex.value = val;
		// console.log('index-----------', val);
		emit('changeItem', value);
	};

	onMounted(() => {
		fu(props.carouselList);
	});

	/**
	 * 重新处理,el-carousel-item数量为2时,组件循环方向一左一右的问题
	 *
	 * 思路:如果为2时,复制一次,使其成为长度length为4的数组,然后将Carousel组件的indicators(下标显示器)多复制的给隐藏(原本长度为2,现在为4,就隐藏第3个和第4个)
	 * @param data
	 */
	const fu = (data: QueryPosterInfoListOutput[]) => {
		if (data) {
			if (data.length === 2) {
				isTwo.value = true;
				//将2条数据复制一份为4条数据
				carouselListData.value = data.concat(data);
			} else {
				isTwo.value = false;
				//其他时候正常赋值
				carouselListData.value = data;
			}
		}
	};
</script>

<style scoped lang="scss">
	.twoBox {
		width: 100%;
		height: 100%;

		.carouselBox {
			width: 100%;

			//将复制出来的数据的下标隐藏
			:deep(.el-carousel__indicators) {
				& > li:nth-child(3),
				& > li:nth-child(4) {
					display: none;
				}
			}
		}
	}

	.elseBox {
		width: 100%;
		height: 100%;

		.carouselBox {
			width: 100%;
		}
	}
	.carousel {
		:deep {
			.el-carousel__indicators--outside .is-active button {
				background-color: var(--el-color-primary);
				width: 20px;
				height: 3px;
			}
			.el-carousel__indicators--outside button {
				// background-color: #e1e1e1;
				width: 9px;
			}
			.el-carousel__arrow {
				background-color: #8b8b8b;
			}
			.el-carousel__arrow--left {
				left: 16.1%;
				opacity: 40%;
			}
			.el-carousel__arrow--right {
				right: 16.1%;
				opacity: 40%;
			}
			.el-carousel__arrow--right:active,
			.el-carousel__arrow--left:active {
				opacity: 80%;
			}
			.el-carousel__container {
				margin-bottom: 7px;
				position: relative;
				width: 100%;
				height: auto;
				// aspect-ratio: 1440/600
				img {
					position: absolute;
					top: 0;
					left: 0;
					width: 100%;
					height: 100%;
				}
			}
		}
	}
</style>

2.使用:

基础用法:

<template>
    <my-carousel
        v-if="bannerImgsList.length"
	    :height="'582'"
	    :carouselList="bannerImgsList"
	     @clickGoPage="clickGoPage"
	/>
</template>

<script setup lang="ts">
import { QueryPosterInfoListOutput } from '@/api/home/types';
const bannerImgsList = ref<QueryPosterInfoListOutput[]>([]);

const clickGoPage = (value: IcarouselList) => {
		console.log('=====', value);
		// router.push("/home");
};
</script>

 需要结合tab来动态联动的用法:

<template>
	<div class="step-package margin-top40" v-if="ladderPackageList && ladderPackageList.length">
		<!-- 切换的tab -->
		<div class="flex-center margin-top20">
			<div
				v-for="item in ladderPackageList"
				:key="item.id"
				class="step-package-tabs"
				:class="{ 'step-package-tabs-active': activeTab == item.id }"
			>
				<el-button class="img-button" @click="clickSelectTab(item)">
					{{ item.posterName }}
				</el-button>
			</div>
		</div>
		<!-- 轮播图 -->
		<div class="margin-top30 step-carousel">
			<my-carousel
				:height="'422'"
				:width="1000"
				:carouselList="ladderPackageList"
				@changeItem="changeItem"
				@clickGoPage="clickGoPage"
				:activeTab="activeTab"
			/>
		</div>
	</div>
</template>
<script setup lang="ts">
	import { ref } from 'vue'
	import { useRouter } from 'vue-router';
	import { queryFrontLadderPackageFront } from '@/api/ladderPackage';
	import { QueryLadderPackageOutput } from '@/api/ladderPackage/types';
	const router = useRouter();

	const ladderPackageList = ref();
	const activeTab = ref<number>(0);

	onMounted(() => {
		getData ();
	});
	const getData = async () => {
		const result = await 接口;
		if (result && result.length) {
			ladderPackageList.value = result;
			activeTab.value = result[0].id;
		}
	};

	const clickSelectTab = (item: QueryLadderPackageOutput) => {
		activeTab.value = item.id;
	};

	const clickGoPage = (val: any) => {
		console.log('val', val);
	};
	const changeItem = (val: any) => {
		activeTab.value = val.id;
	};
</script>
<style lang="scss" scoped>
	.step-package {
		height: 100%;
		width: 100%;
		.step-package-content {
			width: 70%;
			margin: 0 auto;
		}
		.step-carousel {
			:deep {
				.el-carousel__container {
					aspect-ratio: 1440/420;
				}
			}
		}
		.step-package-tabs {
			margin: 0 3em;
			cursor: pointer;
			border-radius: 16px;
			.img-button {
				border: 0;
				border-radius: 16px;
			}
		}
		.step-package-tabs-active {
			margin: 0 3em;
			background-color: var(--el-color-primary);
			color: #fff;
			.img-button {
				background-color: var(--el-color-primary);
				border-color: var(--el-color-primary);
				color: #fff;
			}
		}
	}
</style>

3.效果图:

最后,同个点击上面的tab切换到不同的图片上,同理,切换不同的轮播图,上面的tab也会跟着动,双向的联动。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/570709.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

08 IO-字符流其它流

IO-字符流&其它流 **字节流&#xff1a;**适合复制文件等&#xff0c;不适合读写文本文件 **字符流&#xff1a;**适合读写文本文件内容 IO流体系 字符流 FileReader&#xff08;文件字符输入流&#xff09; 作用&#xff1a;以内存为基准&#xff0c;可以把文件中的数…

盛水最多的容器 ---- 双指针

题目链接 题目: 分析: 最大容积 即使就是最大面积, 长为下标之差, 宽为两下标对应值的最小值解法一: 暴力枚举: 将每两个数之间的面积都求出来, 找最大值, 时间复杂度较高解法二: 假设我们的数组是[6, 2, 5, 4], 我们先假设最左边和最右边, 即6 和 4 之间是最大面积长a*宽b此…

Android --- 常见UI组件

TextView 文本视图 设置字体大小&#xff1a;android:textSize"20sp" 用sp 设置颜色&#xff1a;android:textColor"#00ffff" 设置倍距(行距)&#xff1a;android:lineSpacingMultiplier"2" 设置具体行距&#xff1a;android:lineSpacingExtra&q…

Day06-Java进阶-Arrays数组工具类冒泡排序选择排序二分查找正则表达式正则爬取

1. Arrays数组工具类 package arrays;import java.util.Arrays;public class ArraysDemo {/*Arrays类常用方法 :----------------------------------------------------------------------public static String toString (类型[] a) : 将数组元素拼接为带有格式的字符串public …

直接用表征还是润色改写?LLM用于文生图prompt语义增强的两种范式

直接用表征还是润色改写&#xff1f;LLM用于文生图prompt语义增强的两种范式 导语 目前的文生图模型大多数都是使用 CLIP text encoder 作为 prompt 文本编码器。众所周知&#xff0c;由于训练数据是从网络上爬取的简单图文对&#xff0c;CLIP 只能理解简单语义&#xff0c;而…

SpringBoot引入第三方jar包或本地jar包

idea2018创建spring boot项目 New Project窗口选择Spring Initializr Type选择Maven(Generate…),有两个Maven选择这一个。 勾选Spring Web。 pom.xml中version改成2.5.10。 在resources中新建jar目录&#xff0c;将第三方jar包fastjson2-2.0.47.jar放入其中。&#xff08…

星球大战绝地幸存者XGP微软商店免费领取教程(XGP注册+开通)

星球大战绝地幸存者XGP微软商店免费领取教程&#xff08;XGP注册开通&#xff09; 《星球大战绝地幸存者》这款游戏是由重生游戏工作室制作&#xff0c;EA发行的冒险类动作游戏&#xff0c;续写了《星球大战绝地&#xff1a;陨落的武士团》中的故事。在这款银河系第三人称动作…

数据仓库与数据挖掘(实验一2024.4.24)

实验准备&#xff1a; 1.下载conda 2.配置环境C:\ProgramData\miniconda3\Scripts 3.创建文件夹panda进入虚拟环境qq 激活虚拟环境&#xff1a;activate qq 启动jupyter lab&#xff08;python语言环境编译&#xff09;&#xff1a;jupyter lab 4.panda下载 &#xff08;…

C 语言实例 - 数值比较

比较两个数 以下实例中定义了两个整数变量&#xff0c;并使用 if 来比较两个数值&#xff0c;可以先看下逻辑图&#xff1a; #include <stdio.h>int main() {int a, b;a 11;b 99;// 也可以通过以下代码实现让用户在终端输入两个数// printf("输入第一个值:&quo…

VS2022配置和搭建QT

一、下载QT 可以去QT官网下载:https://www.qt.io/product/development-tools。 直接安装。 二、安装qt插件 直接在vs插件市场搜索就行。 安装的时候根据提示&#xff0c;关闭vs自动安装 再次进去vs提示你选择qt版本&#xff0c;psth里边找到安装版本的qmake.exe就行 配…

如何让一个大几千页的打开巨慢的 PDF 秒开

生成 PDF 的方法&#xff0c;无论软件还是纯命令的都有很多种&#xff0c;排除计算机性能的因素&#xff0c;并不是所有的方法生成几千页的 PDF 都能丝滑到秒开。 示例 PDF 文档 6 千多页 打开要等一会儿&#xff0c;再等一会儿…… 解决方法 方法一、拆分再合并&#xff08…

css盒子设置圆角边框的方法

前言 欢迎来到我的博客 个人主页&#xff1a;北岭敲键盘的荒漠猫-CSDN博客 本文为我整理的设置圆角边框的方法 需求描述 我们在设置盒子边框时&#xff0c;他总是方方正正的。 我们想让这个直直的边框委婉一点该怎么办呢。这个就提到了我们这篇文章讲的东西&#xff1a; bord…

接口测试|超详细面试题【附答案】

今天给姐妹们整理了一套超详细的附答案的接口测试面试题&#xff0c;姐妹们快学起来吧~ 接口测试的重要性&#xff0c;相信不用我多说了。接口测试是现在软件测试工程师一个加分项。因为很多朋友一开始做了几年的软件测试都是在做功能测试&#xff0c;做界面UI的测试&#xff…

ClickHouse用UDF解析XML字符串和XML文件

一.如果是读取xml文件的时候&#xff0c;文件入库需要使用文件读取UDF 创建了1个测试文件 wsdFileRead()&#xff1a; 直接读取文件内容 SELECT wsdFileRead(/home/temp/wsd_test.xml)Query id: 09b6e5fe-7169-43f7-b001-90e2eeabb8da┌─wsdFileRead(/home/temp/wsd_test.xm…

二维码存储图片如何实现?相册二维码的制作技巧

如何将照片生成二维码后存储展示&#xff1f;现在很多人会将图片生成二维码以后&#xff0c;用于分享或者储存的用途&#xff0c;减少个人内存的占用量&#xff0c;而且分享照片也会更加的方便&#xff0c;只需要扫描二维码就可以让其他人查看图片。 想要制作图片二维码的步骤…

掌握Linux Shell脚本函数:提高脚本效率与可维护性

目录标题 1、什么是Shell函数&#xff1f;2、如何定义Shell函数&#xff1f;3、Shell函数参数4、返回值5、实例&#xff1a;使用函数进行文件备份6、为什么使用函数&#xff1f;7、最佳实践 在编写Linux shell脚本时&#xff0c;函数是组织和重用代码的重要手段。本文将介绍如何…

ubuntu20 中设置桌面背景任务

1. 下载conky 使用 Conky 在 Ubuntu 中显示信息&#xff0c;例如你的阅读计划&#xff0c;可以分几个步骤来完成。Conky 是一款灵活的轻量级系统监视器&#xff0c;能够在桌面上显示各种信息。以下是基本的设置步骤&#xff1a; 安装 Conky 首先&#xff0c;你需要在 Ubuntu…

园区智慧化转型新篇章:解码智慧技术如何助力园区实现精细化管理,提升运营效率

目录 一、智慧技术概述及其在园区管理中的应用 &#xff08;一&#xff09;物联网技术的应用 &#xff08;二&#xff09;大数据技术的应用 &#xff08;三&#xff09;云计算技术的应用 二、智慧技术助力园区实现精细化管理 &#xff08;一&#xff09;实现资源优化配置…

百度智能云千帆 ModelBuilder 技术实践系列:通过 SDK 快速构建并发布垂域模型

​百度智能云千帆大模型平台&#xff08;百度智能云千帆大模型平台 ModelBuilder&#xff09;作为面向企业开发者的一站式大模型开发平台&#xff0c;自上线以来受到了广大开发者、企业的关注。至今已经上线收纳了超过 70 种预置模型服务&#xff0c;用户可以快速的调用&#x…

crossover和wine哪个好 wine和crossover有什么本质区别 苹果电脑运行Windows crossover24

CrossOver是Wine的延伸产品&#xff0c;CrossOver可以简单的理解为类虚拟机&#xff0c;那么wine是什么&#xff0c;许多小伙伴就可能有些一知半解。CrossOver和wine哪个好&#xff0c;wine和CrossOver有什么本质区别呢&#xff1f;下文将围绕着这两个问题展开。 一、CrossOve…