这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战。
大家好,我是张三岁🤣,一只法系前端⚖️。爱分享🖋️、爱冰冰🧊🧊。
欢迎小伙伴们加我微信:maomaoibingbing,拉你进群,一起讨论,期待与大家共同成长🥂。
前言
最近项目中需要用到轮播图,我立马想起了 swiper
,那么本文就来带大家体验一下如何在 React
中使用这个插件,并且有哪些需要注意的地方。
一、需求简介
需求非常简单,就是一个可以自动播放、点击切换的轮播图(跑马灯),可以同时展示六张图片,无限滚动。如下图所示:
二、开始编码
1. 查看官方文档
用轮子的第一步永远是看官方文档,此处附上传送门:
2. 安装依赖
npm i swiper
# or
yarn add swiper
3. 运行官网案例(出错)
先将官网上的示例代码复制并运行一下,由于项目使用的是 TypeScript
,故此处使用的 tsx
。
// src/pages/Demo/index.tsx
import React from 'react';
// Import Swiper React components
import { Swiper, SwiperSlide } from 'swiper/react';
// Import Swiper styles
import 'swiper/css';
const Demo: React.FC = () => {
return (
<Swiper
spaceBetween={50}
slidesPerView={3}
onSlideChange={() => console.log('slide change')}
onSwiper={(swiper) => console.log(swiper)}
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
<SwiperSlide>Slide 4</SwiperSlide>
</Swiper>
);
};
export default Demo;
然后页面效果是这样的:
终端报错:AssertionError [ERR_ASSERTION]: filePath not found of swiper/react
。我还以为是我改出了问题,就直接新建了 jsx
文件,然后不经修改直接粘贴过去,结果还是一样的报错(此处我就不放示例代码了)。
4. 解决当前问题
4.1 分析问题
查看报错信息,似乎是 CSS
文件引入出错,且 swiper/react
也没有找到或引入失败。我对此问题的原因进行了以下猜测:
- 可能是依赖的安装出错
- 可能是官网的案例出错
- 可能是插件自身问题
4.2 寻找解决方案
在经过多次尝试解决并失败后,我又从报错信息入手,使用了百度大法。终于发现了一篇能解决当前问题文章:《关于 antd pro 使用 swiper7 的问题》。文章指出,是由于插件版本的不兼容导致的当前问题。
4.3 尝试解决
4.3.1 降级为 swiper6.8.4
移除之前的最新 7.x
版本,改用 6.8.4
版本。(实验得出 6.5
同样报错,暂未测试其他版本)此处附上 swiper6.x
的官网传送门:Swiper React Components
yarn remove swiper
yarn add swiper@6.8.4
4.3.2 修改引入样式文件
- import 'swiper/css';
+ import 'swiper/swiper-bundle.css';
4.3.3 查看效果
真是千呼万唤始出来,忙了半天总算可以正常显示了,接下来就对其进行完善,以达到预期效果。
5. 实现效果
5.1 基本样式
引入图片,修改样式。直接上代码:
// src/pages/Demo/index.tsx
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper-bundle.css';
import styles from './index.less';
const Demo: React.FC = () => {
const partnerLogo: Array<string> = [
require('@/assets/images/demo/partner-logo-1.png'),
require('@/assets/images/demo/partner-logo-2.png'),
require('@/assets/images/demo/partner-logo-3.png'),
require('@/assets/images/demo/partner-logo-4.png'),
require('@/assets/images/demo/partner-logo-5.png'),
require('@/assets/images/demo/partner-logo-6.png'),
];
return (
<div className={styles.demo}>
<Swiper spaceBetween={20} slidesPerView={6} loop>
{partnerLogo.map((value, index) => {
return (
<SwiperSlide key={index}>
<img className={styles.item} src={value} />
</SwiperSlide>
);
})}
</Swiper>
</div>
);
};
export default Demo;
// src/pages/Demo/index.less
.demo {
position: relative;
margin: 0 auto;
width: 1200px;
min-width: 1200px;
.item {
margin: 50px 0;
width: 162px;
box-shadow: 3px 6px 8px #dde0e8;
}
}
看一下效果:
5.2 自动轮播效果
根据文档描述,非核心模块需要引入才能使用。此处附上 swiper6.x
官网描述与译文:
By default Swiper React uses core version of Swiper (without any additional modules). If you want to use Navigation, Pagination and other modules, you have to install them first.
默认情况下,Swiper React使用了Swiper的核心版本(没有任何额外的模块)。如果您想使用导航、分页和其他模块,您必须首先安装它们。
直接上代码:
// src/pages/Demo/index.tsx
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper-bundle.css';
import styles from './index.less';
// 增加以下代码以使用"自动轮播"功能
import SwiperCore, { Autoplay } from 'swiper';
SwiperCore.use([Autoplay]);
const Demo: React.FC = () => {
const partnerLogo: Array<string> = [
// ...
];
return (
<div className={styles.demo}>
{/* 增加"autoplay" */}
<Swiper spaceBetween={20} slidesPerView={6} loop autoplay>
{partnerLogo.map((value, index) => {
return (
<SwiperSlide key={index}>
<img className={styles.item} src={value} />
</SwiperSlide>
);
})}
</Swiper>
</div>
);
};
export default Demo;
自动轮播效果如下:
5.3 前进后退按钮
增加两个图片作为前进/后退的按钮,并增加相应的样式。
// src/pages/Demo/index.tsx
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Autoplay, Navigation } from 'swiper';
import 'swiper/swiper-bundle.css';
import styles from './index.less';
import imgPrev from '@/assets/images/demo/prev.png';
import imgNext from '@/assets/images/demo/next.png';
SwiperCore.use([Autoplay, Navigation]);
const Demo: React.FC = () => {
const partnerLogo: Array<string> = [
// ...
];
return (
<div className={styles.demo}>
<img className={styles.prev} src={imgPrev} />
<img className={styles.next} src={imgNext} />
<Swiper
spaceBetween={20}
slidesPerView={6}
loop
autoplay
navigation={{ prevEl: `.${styles.prev}`, nextEl: `.${styles.next}` }}
>
{partnerLogo.map((value, index) => {
return (
<SwiperSlide key={index}>
<img className={styles.item} src={value} />
</SwiperSlide>
);
})}
</Swiper>
</div>
);
};
export default Demo;
// src/pages/Demo/index.less
.demo {
position: relative;
margin: 0 auto;
width: 1200px;
min-width: 1200px;
.prev,
.next {
position: absolute;
top: 72px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
.prev {
left: -70px;
}
.next {
right: -70px;
}
.item {
margin: 50px 0;
width: 162px;
box-shadow: 3px 6px 8px #dde0e8;
}
}
最终效果如图所示: