介绍
环境版本
Swiper 11.2.5
Vue 3.5.13
安装
pnpm install swiper --save
流程
注意
Swiper 组件 11 用的都是组件,所以属性必须要绑定在组件上,不能直接写在标签上,比如:
:slidesPerView="1"
而不是slidesPerView="1"
。Swiper 组件 11 例如分页器,自动轮播,都必须要引入模块和对应的样式,否则无法使用。
Swiper 组件 11 最重要的就是 @swiper 通过这个方法能获取到实例,实例上面就有对应的方法
基础版效果
属性介绍
slidesPerView
注意
设置 slider 容器能够同时显示的 slides 数量(carousel 模式)。
可以设置为数字(小数不可 loop),或者 'auto'则自动根据 slides 的宽度来设定数量。
autoplay
注意
autoplay:{ delay: 2000 ,disableOnInteraction: false }
autoplay 为自动切换函数;
delay:轮播项的延迟时间;
disableOnInteraction:用户操作之后时候禁止自动切换。
navigation
注意
使用前进后退按钮来控制 Swiper 切换。
pagination
- 默认(无需自定义):
注意
pagination="{ type: 'bullets', clickable: true }"
pagination:使用分页器导航;
type:分页器样式;
clickable 是否可点击跳转到对应图片。
- pagination 自定义值
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>`;
},
});
注意
el 代表绑定的元素
clickable 是否可点击跳转到对应图片。
bulletClass 分页器容器类名。
bulletActiveClass 分页器活跃的类
scrollbar
注意
scrollbar="{ draggable: true }"
scrollbar:设置滚动条,draggable:该参数设置为 true 时允许拖动滚动条。
direction
注意
Swiper 的滑动方向,可设置为水平方向切换 horizontal 或垂直方向切换 vertical 。
space-between
注意
在 slide 之间设置距离(单位 px)。
modules
注意
在项目中引入 swiper 时,需要用到的 Swiper 模块。
事件介绍
@swiper
注意
事件函数,返回 swiper 实例
@slideChange
注意
事件函数。在当前 Slide 切换到另一个 Slide 时执行(activeIndex 发生改变),一般是在点击控制组件、释放滑动的时间点。
基础案例
<template>
<div class="swiperwrap">
<div class="swipercontent">
<swiper
:slidesPerView="1"
:autoplay="{ delay: 2000, disableOnInteraction: false }"
:scrollbar="{ draggable: false }"
:space-between="0"
:modules="modules"
:loop="true"
:pagination="paginationref"
@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 {
Autoplay,
Navigation,
Pagination,
Scrollbar,
A11y,
} 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",
},
];
let modules = [Autoplay, Navigation, Pagination, Scrollbar];
//定义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: 273px;
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: rgb(229, 127, 141);
}
: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: blue;
.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>