Vue3轮播图左右联动

1、轮播图部分,右边鼠标移入,左边对应展示轮播图

可以在swiper 官网

Swiper中文网-轮播图幻灯片js插件,H5页面前端开发

选择vue中使用swiper

  npm i swiper

左右两边的联动:左边的轮播图和右边的小的列表他们的列表组成结构是一样的,都是一样的数组,这样才能够在右边鼠标移入的时候获取到下标与左边的下标相对应 找到对应的元素。

2.右侧鼠标移入高亮

通过视频可以看出,鼠标高亮部分 紫色背景没有被其他的图片所盖住,而是展示在了上面的位置,因此,给每一个列表都单独添加一个div盒子来写紫色高亮部分,使用绝对定位来决定盒子的位置,在通过z-index 来控制盒子里面的内容层级关系,通过index属性来进行判断是否紫色盒子是否展示的问题。

javascript 复制代码
<template>
	<div style="display: flex">
		<div class="container">
			<div class="container-bg">
				<div class="container-nr">
					<!--  左边轮播图-->
					<div class="nr-left">
						<swiper
							@swiper="setControlledSwiper"
							:modules="modules"
							:slides-per-view="1"
							:space-between="50"
							initialSlide="0"
							:autoplay="{ delay: 2500, disableOnInteraction: false }"
							navigation
							:pagination="{ clickable: true }"
							:scrollbar="{ draggable: true }">
							<swiper-slide v-for="(item, index) in list">
								<div class="swiper-item">
									<img :src="item.img" />
									<div class="img-introduce">
										<div class="title">{{ item.title }}</div>
										<div class="content">{{ item.content }}</div>
									</div>
								</div>
							</swiper-slide>
						</swiper>
					</div>
					<!-- 右边轮播图-->
					<div class="nr-right">
						<div
							:class="['nr-right-list', { activeList: activeList === index }]"
							v-for="(item, index) in list"
							@mouseenter="onmouseenter(index)">
							<div class="nr-right-dc" v-show="activeList === index"></div>
							<div class="nr-right-content">
								<div class="nr-right-list-left">{{ item.title }}</div>
								<div class="nr-right-list-right">
									<img style="width: 150px; height: 125px" :src="item.img" />
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>
<script setup>
// 导入需要的模块 自动播放,导航模块,分页,滚动条模式,辅助功能模块
import { Autoplay, Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules'
import { Swiper, SwiperSlide } from 'swiper/vue'
// 引入swiper 相关的样式
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
import 'swiper/css/scrollbar'
import 'swiper/css/autoplay'
import { onMounted, ref } from 'vue'
const activeList = ref(0)
const modules = ref([Autoplay, Navigation, Pagination, Scrollbar, A11y])
// 用来获取swiper 组件实例
const mySwiper = ref(null)
// swiper 组件以及右边列表轮播图 数组
const list = ref([
	{
		img: 'https://img2.baidu.com/it/u=248779163,487887586&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500',
		title: '2024年畅销榜图书推荐',
		content: '当地时间2024年12月12日上午,2024世界慕课与世界大会在美国举办'
	},
	{
		img: 'https://img1.baidu.com/it/u=2351041742,3087776587&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
		title: '2025年度最受欢迎人气作家',
		content: '清华大学等你投票'
	},
	{
		img: 'https://img1.baidu.com/it/u=3275395028,3906211172&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
		title: '2025年度热搜排行榜'
	},
	{
		img: 'https://img2.baidu.com/it/u=4052861714,3377805952&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
		title: '2024世界慕课在线教育大会在伦敦举行'
	}
])

// 初始化 默认第一个轮播图高亮是第一个元素
onMounted(() => {
	mouseEvent(0)
})

// 用来获取swiper 组件实例
const setControlledSwiper = (swiper) => {
	mySwiper.value = swiper
}

// 鼠标移入事件
const onmouseenter = (index) => {
	mouseEvent(index)
}
// 通用事件,初始化以及鼠标移入的时候共同调用
const mouseEvent = (index) => {
	// 获取高亮的index
	activeList.value = index
	// 获取右边轮播图高亮块元素
	let imgList = document.getElementsByClassName('nr-right-dc')
	// 获取右边轮播图元素的内容盒子
	let imgContent = document.getElementsByClassName('nr-right-content')
	// 由于获取到的是伪数组,通过Array.from 进行转化
	var elementsArray = Array.from(imgList)
	var imgContentArray = Array.from(imgContent)

	// 进行循环 调整层级关系
	elementsArray.forEach((item, i) => {
		if (i === index) {
			item.style.zIndex = '52'
		} else {
			item.style.zIndex = '50'
		}
	})

	imgContentArray.forEach((item, i) => {
		if (i === index) {
			item.style.zIndex = '53'
		} else {
			item.style.zIndex = '51'
		}
	})
	// slideTo跳转到指定的swiper轮播图
	mySwiper.value.slideTo(index)
}
</script>
<style lang="scss">
.container {
	width: 1000px;
	height: 500px;
	margin-right: 10px;
	margin-left: 40px;
	.container-bg {
		width: 1000px;
		height: 500px;
		background: linear-gradient(45deg, #791cb5 60%, transparent);
		margin-left: 30px;
		position: relative;
	}
	.container-nr {
		width: 1000px;
		height: 500px;
		position: absolute;
		background: #eeeeee;
		left: -40px;
		top: 40px;
		display: flex;
		.nr-left {
			width: 700px;
			height: 500px;
			cursor: pointer;
		}
		.nr-right {
			width: 300px;
			height: 500px;
			cursor: pointer;
			.nr-right-list {
				width: 100%;
				height: 125px;
				display: flex;
				position: relative;
				.nr-right-dc {
					width: 330px;
					height: 138px;
					background-color: #8c3cbf;
					position: absolute;
					left: -23px;
					top: -5px;
					z-index: 50;
				}
				.nr-right-content {
					position: absolute;
					display: flex;
					z-index: 51;
				}
				.nr-right-list-left {
					width: 150px;
					height: 125px;
					font-weight: bold;
					box-sizing: border-box;
					padding: 10px;
					font-size: 12px;
				}
				.nr-right-list-right {
					width: 100px;
					height: 125px;
				}
			}
		}
	}
}
.swiper-item {
	position: relative;
	.img-introduce {
		color: #ffffff;
		position: absolute;
		bottom: 3px;
		left: 0px;
		width: 700px;
		height: 70px;
		box-sizing: border-box;
		padding: 10px;
		font-weight: bold;
		background: linear-gradient(to top, #2b0c35, transparent);
		.title {
			margin-bottom: 9px;
		}
		.content {
			font-size: 8px;
			font-weight: normal;
		}
	}
}
.box {
	width: 300px;
	height: 700px;
	background-color: #f2f3f9;
	.content-box {
		width: 300px;
		height: 600px;
		position: relative;
		left: -20px;
		top: 20px;
		background: linear-gradient(135deg, #791cb5 60%, transparent);
		animation: toLeave 1s linear;
	}
	.content-title {
		position: relative;
		font-weight: bold;
		left: -20px;
		top: 20px;
	}
	.box-title {
		display: flex;
		.box-title-style {
			position: relative;
		}
	}
	@keyframes toHeight {
		0% {
			width: 0px;
		}
		100% {
			width: 40px;
		}
	}
	.active {
		background-color: #791cb5;
		color: #ffffff !important;
		position: relative;
	}
	.active::before {
		position: absolute;
		left: 0;
		top: 50%;
		transform: translateY(-50%) scaleY(0.5);
		content: '';
		height: 1px;
		width: 40px;
		background: #ffffff;
		animation: toHeight 1s linear;
	}
	@keyframes toLeave {
		0% {
			height: 0px;
		}
		100% {
			height: 600px;
		}
	}
}
.activeList {
	color: #ffffff;
}
</style>
相关推荐
liro1 小时前
HTML5和CSS3新增属性简要概括
前端
工业互联网专业1 小时前
基于springboot+vue的城市公交查询系统
java·vue.js·spring boot·毕业设计·源码·课程设计
冴羽1 小时前
Svelte 最新中文文档翻译(1)—— 概述与入门指南
前端·javascript·vue.js·svelte·sveltekit
gqkmiss1 小时前
Chrome 132 版本新特性
前端·chrome·浏览器·chrome 132
颜酱1 小时前
element-ui实现动态表单点击按钮新增行/删除行
前端·javascript·vue.js
诸神缄默不语1 小时前
HTML中的`<!DOCTYPE html>`是什么意思?
前端·html
放逐者-保持本心,方可放逐1 小时前
HTML-BFC+SEO+标签应用实例
前端·html·seo·语义化标签·标签实例
如影随从1 小时前
08-ArcGIS For JavaScript-通过Mesh绘制几何体(Cylinder,Circle,Box,Pyramid)
开发语言·javascript·arcgis·mesh·pyramid·cylinder·circle
Dontla2 小时前
React技术栈搭配(全栈)(MERN栈、PERN栈)
前端·react.js·前端框架
心.c2 小时前
vue知识点总结
前端·javascript·vue.js