You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Swiper.js开启loop且配置slidesPerView时,分页按钮滑动异常(slideToLoop仅单张滑动)问题求助

React中Swiper.js开启loop且配置slidesPerView时,分页按钮滑动异常(slideToLoop仅单张滑动)问题求助

我目前在使用Swiper.js的React封装实现轮播组件,需求是:

  • 拥有「上一页」「下一页」按钮,每次切换单个slide,这部分功能已经正常工作
  • 添加分页按钮(Dots),根据代码中配置的breakpoints里的slidesPerView参数,点击分页按钮直接跳转到对应页的起始位置

但现在遇到了棘手的问题:当轮播开启loop循环模式,并且配置了slidesPerView多列展示时,分页按钮的滑动逻辑异常,核心问题是调用slideToLoop方法时,有时候只会滑动单个slide,哪怕传入静态的索引0也会出现这个问题。

下面是我的完整代码,麻烦帮忙排查一下问题所在:


import { Swiper, SwiperSlide } from "swiper/react";
import ArtistCard from "../songcards/artistcard";
import { useEffect, useRef, useState } from "react";
import { NextSvg, PrevSvg } from "../../assets/svg";

const Dots = ({ swiperRef, slideLength }) => {
  const [index, setIndex] = useState(0);
  const [pageLength, setPageLength] = useState(0);

  const changeSlide = (index) => {
    const newIndex = Math.floor(
      (swiperRef.current.slides.length / pageLength) * index
    );
    swiperRef.current?.slideToLoop(newIndex);
  };

  useEffect(() => {
    const swiperEle = swiperRef.current;

    const handleChange = () => {
      const curr_index = swiperEle.realIndex;
      const per_page = Math.floor(slideLength / pageLength);
      setIndex(Math.floor(curr_index / per_page));
    };

    if (swiperEle) swiperEle.on("slideChange", handleChange);

    return () => {
      if (swiperEle) swiperEle.off("slideChange", handleChange);
    };
  }, [swiperRef, pageLength, slideLength]);

  useEffect(() => {
    const updateSlidesPerView = () => {
      const width = window.innerWidth;
      if (width >= 1024) {
        setPageLength(slideLength / 6);
      } else if (width >= 768) {
        setPageLength(slideLength / 4);
      } else if (width >= 640) {
        setPageLength(slideLength / 3);
      } else {
        setPageLength(slideLength / 2);
      }
    };
    updateSlidesPerView();

    window.addEventListener("resize", updateSlidesPerView);

    return () => {
      window.removeEventListener("resize", updateSlidesPerView);
    };
  }, [slideLength]);

  if (pageLength)
    return (
      <>
        {Array.from({ length: pageLength }).map((_, dotIndex) => (
          <span
            key={dotIndex}
            className={`${dotIndex} cursor-pointer h-[4px] inline-block rounded-sm transition-all duration-300 ${
              dotIndex === index ? "w-5 bg-white" : "w-[10px] bg-[#c0c0c0]"
            } ${dotIndex === pageLength - 1 ? "" : "mr-[10px]"}`}
            onClick={() => changeSlide(dotIndex)}
          ></span>
        ))}
      </>
    );
};

const HeroArtistsCarousal = () => {
  const swiperRef = useRef(null);

  const handleNext = () => swiperRef.current && swiperRef.current.slideNext();
  const handlePrev = () => swiperRef.current && swiperRef.current.slidePrev();

  const artists = [...];

  return (
    <div className="relative">
      <Swiper
        spaceBetween={30}
        slidesPerView={2}
        loop={true}
        breakpoints={{
          640: {
            slidesPerView: 3,
          },
          768: {
            slidesPerView: 4,
          },
          1024: {
            slidesPerView: 6,
          },
        }}
        onSwiper={(swiperInstance) => {
          swiperRef.current = swiperInstance;
        }}
      >
        {artists.map((artist) => (
          <SwiperSlide key={artist.id}>
            <ArtistCard artist={artist} />
          </SwiperSlide>
        ))}
      </Swiper>
      <div className="mt-7 flex justify-end items-center">
        <Dots swiperRef={swiperRef} slideLength={artists.length} />
        <button
          onClick={handlePrev}
          className="hidden 2lg:inline-block ml-[10px]"
        >
          <PrevSvg className="fill-white hover:fill-[#25a56a] w-[30px] h-[30px] transition-colors duration-300" />
        </button>
        <button onClick={handleNext} className="hidden 2lg:inline-block">
          <NextSvg className="fill-white hover:fill-[#25a56a] w-[30px] h-[30px] transition-colors duration-300" />
        </button>
      </div>
    </div>
  );
};

export default HeroArtistsCarousal;

非常感谢大家的帮助!

备注:内容来源于stack exchange,提问作者Harsh Narwariya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:59:31