vue3实现swiper一次显示多个,竖着排列,多行多列,点击下一页挪动一列。
·
通过 Swiper 组件实现了游戏列表的轮播展示,根据设备类型动态调整每页显示的游戏数量和布局,并且为每个游戏项添加了点击事件以跳转到详细页面。
展示效果:
1.安装依赖:(我安装的是"swiper": “^11.1.12”,)
npm i swiper
2.template代码:
<template>
<div>
<!-- tab -->
<div class="tab-search">
<div class="itemBox overflow-x-scroll flex items-center justify-start ">
<div class="tab-search-item " :class="{ actived: isActive === item.id }" v-for="item in tabList" :key="item.id"
@click="changeTab(item)">
<i class="iconfont" :class="item.icon"></i>
<!-- <span>{{ $t(`${item.langTitle}`) }}</span> -->
<span>{{ item.name }}</span>
</div>
</div>
<div class="search-icon">
<van-icon name="search" color="#0FE1A9" />
</div>
</div>
<!-- 内容 -->
<div class="content">
<div class="gameList" v-for="(i, idx) in filtersList" :key="i.typeName">
<div class="titleContent">
<div class="title">
<i class="iconfont text-45 fontColor pr-10" :class="i.icon" />
<span class="text-28 ">{{ i.typeName }}</span>
<div class="Rtp bg-fff-5 text-fff px-20 ml-20 text-20" v-if="!isMobile">
<i class="iconfont icon-lightning text-fff mr-5"></i>
<span class=" ">RTP até </span>
<span class="text-ffee92 ml-5">{{ i.hot }}</span>
</div>
</div>
<div class="switch">
<div class="mais">{{ $t('More') }}</div>
<div class="arrow_left" @click="prevSlide(idx)">
<!-- <i class="iconfont icon-cha"></i> -->
<van-icon name="arrow-left" size="14" color="#4D4F54" />
</div>
<div class="arrow_right" @click="nextSlide(idx)" :disabled="disabledEnd">
<!-- <i class="iconfont icon-jinbi"></i> -->
<van-icon name="arrow" size="14" color="#4D4F54" />
</div>
</div>
</div>
<div class="centerDiv" v-if="isMobile">
<!-- <van-icon name="sort" /> -->
<i class="iconfont icon-lightning text-fff"></i>
<span>RTP até </span>
<span>{{ i.hot }}</span>
</div>
<div class="list">
<!-- :autoplay="swiperOption.autoplay" ref="mySwiper"
@swiper="onSwiper" -->
<Swiper :ref="`mySwiper${idx}`" @swiper="onSwiper(idx, $event)" :autoplay="false" :modules="modules"
:slides-per-view="isMobile ? 4 : 7" :grid="{
fill: 'row',
rows: 3,
}" :spaceBetween="isMobile ? 6 : 50" :prevent-clicks-propagation="false" class="wrap">
<SwiperSlide v-for="(item, index) in i.data" :key="index" class="swiper-slide chart"
@click="handleDetail(item)">
<!-- {{ item }} -->
<div class=" relative ">
<img :src="`${domain.picture}${item.gameIcon}`" alt="" />
<div
class="absolute top-0 left-0 w-60 h-35 rounded-r-40px text-24 text-fff bg-gradient-to-b from-[#FF0F47] to-[#FFAB96] content-center pl-7 shasowYy">
Top</div>
<div
class="absolute top-2 right-2 w-31 h-31 leading-31 bg-[rgba(113,113,113,0.71)] content-center text-center rounded-50%">
<i class="iconfont icon-xingxing fontSize14 text-fff"
:class="{ 'text-gradient ': isLike == true }"></i>
</div>
</div>
</SwiperSlide>
</Swiper>
</div>
</div>
<div v-if="!filtersList.length" class="text-center mt-30">暂无数据</div>
</div>
</div>
</template>
3.js代码
import { computed, onMounted, ref } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import "swiper/css";
import "swiper/css/grid";
import { Autoplay, Grid } from "swiper/modules";
let isActive = ref(0);
let disabledEnd = ref(false);
const swiperRefs = ref([]);
// 切换tab数据过滤
const filtersList = computed(() => {
if (isActive.value === 0) {
return dataList.value.filter(item => item.hasOwnProperty('data'))
} else {
return dataList.value.filter(item => item.type === isActive.value && item.hasOwnProperty('data'))
}
})
const changeTab = (e) => {
isActive.value = e.id
}
// 添加一个用于存储每个swiper当前页码的数组
const currentPages = ref(Array(dataList.value.length).fill(0));
// 监听 swiper 组件的回调函数,同时存储每个swiper的引用
const onSwiper = (index, swiper) => {
swiperRefs.value[index] = swiper;
swiper.on('slideChange', () => {
// 更新当前页码
currentPages.value[index] = swiper.activeIndex;
console.log(swiper);
});
};
// 检查是否在第一页的函数
const isAtFirstPage = (index) => {
return currentPages.value[index] === 0;
};
const isEndPcPage = (index) => {
return (swiperRefs.value[index].slides.length - 12) / 2
}
// 上一页滑动函数
const prevSlide = (index) => {
const swiperInstance = swiperRefs.value[index];
if (swiperInstance.slides && swiperInstance.slides.length < 12) {
showToast({
message: '没有更多数据',
position: 'center',
});
console.log('没有更多数据');
return
}
if(swiperInstance.activeIndex===0 ){
console.log("已经是第一页了",swiperInstance);
showToast({
message: '已是第一页',
position: 'center',
});
} else if (!isAtFirstPage(index) && swiperInstance) {
swiperInstance.slidePrev();
console.log("上一页", swiperInstance,isAtFirstPage(index));
}else{
console.log("已经是第一页了");
showToast({
message: '已是第一页',
position: 'center',
});
}
};
// 切换到下一张幻灯片
const nextSlide = (index) => {
const swiperInstance = swiperRefs.value[index];
if (swiperInstance.slides.length < 12) {
showToast({
message: '没有更多数据',
position: 'center',
});
return false;
}
if (swiperInstance.activeIndex >= isEndPcPage(index) && !isMobile) {
showToast({
message: '已是最后一页',
position: 'center',
});
console.log('已经是最后一张了');
return false;
}
if(swiperInstance.activeIndex >=((swiperInstance.slides.length - 12) / 3)){ //3代表列 12代表每一页个数
showToast({
message: '已是最后一页',
position: 'center',
});
}
else if (!(swiperInstance.activeIndex >= ((swiperInstance.slides.length - 12) / 3)) && swiperInstance) {
swiperRefs.value[index].slideNext();
}else {
disabledEnd.value = true;
showToast({
message: '已是最后一页',
position: 'center',
});
}
};
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)