React 之使用「swiper」

12,173 阅读4分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

大家好,我是张三岁🤣,一只法系前端⚖️。爱分享🖋️、爱冰冰🧊🧊。
欢迎小伙伴们加我微信:maomaoibingbing,拉你进群,一起讨论,期待与大家共同成长🥂。

前言

最近项目中需要用到轮播图,我立马想起了 swiper ,那么本文就来带大家体验一下如何在 React 中使用这个插件,并且有哪些需要注意的地方。

一、需求简介

需求非常简单,就是一个可以自动播放、点击切换的轮播图(跑马灯),可以同时展示六张图片,无限滚动。如下图所示:

效果图.png

二、开始编码

1. 查看官方文档

用轮子的第一步永远是看官方文档,此处附上传送门:

  1. Swiper中文网
  2. Swiper React Components

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;

然后页面效果是这样的:

一引入就报错.png

终端报错:AssertionError [ERR_ASSERTION]: filePath not found of swiper/react 。我还以为是我改出了问题,就直接新建了 jsx 文件,然后不经修改直接粘贴过去,结果还是一样的报错(此处我就不放示例代码了)。

4. 解决当前问题

4.1 分析问题

查看报错信息,似乎是 CSS 文件引入出错,且 swiper/react 也没有找到或引入失败。我对此问题的原因进行了以下猜测:

  1. 可能是依赖的安装出错
  2. 可能是官网的案例出错
  3. 可能是插件自身问题

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 查看效果

可以正常显示了.gif

真是千呼万唤始出来,忙了半天总算可以正常显示了,接下来就对其进行完善,以达到预期效果。

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;
  }
}

看一下效果:

基本样式完成.gif

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;

自动轮播效果如下:

自动轮播.gif

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;
  }
}

最终效果如图所示:

最终效果.gif

参考资料