Swiper 自由模式
效果图
流程
注意
要引入 FreeMode 组件
设置 freeMode: true
代码
vue
<template>
<div class="swiperwrap">
<div class="swipercontent">
<swiper
:slidesPerView="3"
:scrollbar="{ draggable: false }"
:spaceBetween="30"
:freeMode="true"
:modules="modules"
:loop="true"
:pagination="paginationref"
:autoplay="{ delay: 2000, disableOnInteraction: false }"
@mouseenter="enter"
@mouseleave="leave"
@swiper="onSwiper"
@slideChange="onSlideChange"
>
<swiper-slide
v-for="(item, index) in swiperImgArray"
:key="index"
class="swiperItem"
>
<img :src="item.img" alt="" />
</swiper-slide>
</swiper>
<!--分页器-->
<div class="pagination"></div>
</div>
<!--左边-->
<div class="left" @click="handleClick('left')">
<img
src="https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2025/MuNiHei20250314/left.png"
/>
</div>
<!--右边-->
<div class="right" @click="handleClick('right')">
<img
src="https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2025/MuNiHei20250314/right.png"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { toRaw, ref } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import "swiper/css";
import "swiper/css/pagination";
import {
Navigation,
Pagination,
Scrollbar,
A11y,
FreeMode,
Autoplay,
} from "swiper/modules";
interface Item {
img: string;
}
const swiperImgArray: Item[] = [
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/01.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/02.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/03.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/04.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/05.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/01.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/02.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/03.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/04.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/05.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/01.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/02.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/03.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/04.jpg",
},
{
img: "https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/2024/muniheipc/munihei/qiangxiankan/05.jpg",
},
];
let modules = [Navigation, Pagination, Scrollbar, FreeMode, Autoplay];
//定义swiperNew,目的获取非响应式swiper
let swiperNew: any;
//鼠标移入
const enter = () => {
swiperNew.autoplay.stop();
};
//鼠标移出
const leave = () => {
swiperNew.autoplay.start();
};
const onSwiper = (swiper: any) => {
swiperNew = toRaw(swiper); //拿到swiper对象再转换为非响应式
};
const onSlideChange = () => {
console.log("slide change");
console.log(swiperNew);
};
const paginationref = ref({
el: ".pagination",
clickable: true,
bulletClass: "pagination-item",
bulletActiveClass: "active",
renderBullet: (index: number, className: string) => {
return `<div class="${className}"><div class="pagination-item-inner">${
index + 1
}</div></div>`;
},
});
const handleClick = (direction: string) => {
if (direction === "left") {
swiperNew.slidePrev();
} else {
swiperNew.slideNext();
}
};
</script>
<style lang="scss" scoped>
.swiperwrap {
width: 900px;
height: 373px;
background: red;
margin: 0 auto;
position: relative;
margin-top: 120px;
.swipercontent {
width: 508px;
height: 95px;
position: absolute;
left: 50%;
top: 45%;
transform: translate(-50%, -50%);
img {
width: 100%;
height: 100%;
}
.swiperItem {
// border: aqua solid 1px;
// height: 200px;
}
}
.left {
width: 33px;
height: 59px;
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
.right {
width: 33px;
height: 59px;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
:deep(.swiper-pagination)
.swiper-pagination-bullet.swiper-pagination-bullet-active {
background-color: green;
}
:deep(.swiper-pagination-bullet) {
//修改分页器圆点大小
width: 30px;
height: 30px;
background-color: #fff;
}
.swiper-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet,
:deep(.swiper-pagination-horizontal.swiper-pagination-bullets)
.swiper-pagination-bullet {
// 分页器远点之间的距离
margin: 0 10px;
}
.pagination {
width: 210px;
height: 38px;
position: absolute;
left: 50%;
bottom: -57px;
transform: translateX(-50%);
::v-deep(.pagination-item) {
width: 30px;
height: 30px;
border-radius: 50%;
background: white;
margin-top: 5px;
margin-left: 10px;
cursor: pointer;
float: left;
&.active {
background: GREEN;
.pagination-item-inner {
color: yellow;
}
}
.pagination-item-inner {
width: 100%;
height: 100%;
line-height: 20px;
display: flex;
justify-content: center;
align-items: center;
color: black;
text-align: center;
}
}
}
}
</style>