Swiper react | 如何使用 React refs 创建自定义导航/分页组件?

IT技术 reactjs swiper
2021-05-21 04:12:15

SwiperJS 文档指出导航 prevEl/nextEl 可以是“字符串”或“HTMLElement”类型。使用字符串选择器很容易,因为:

const MySwiper = (props) => (
  <Swiper
    navigation={{
      prevEl: '.prev',
      nextEl: '.next',
    }}
    {...props}
  >
    <SwiperSlide>slide 1</SwiperSlide>
    <SwiperSlide>slide 2</SwiperSlide>
    <div className="prev" />
    <div className="next" />
  </Swiper>
)

但是,如何使用 React refs 正确实现使用 HTML 节点而不是字符串选择器允许将导航 prevEl/nextEl 范围限定为MySwiper.

const App = () => (
  <div>
    <MySwiper className="mySwiper1" />
    <MySwiper className="mySwiper2" />
  </div>
)

在APP上面的例子,导航prevEl / Nextel公司从.mySwiper2应该不会引发滑动.mySwiper1,这将与字符串选择发生什么。

我目前的悲伤和hacky解决方法:

const MySwiper = () => {
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)

  return (
    <Swiper
      navigation={{
        // Both prevEl & nextEl are null at render so this does not work
        prevEl: navigationPrevRef.current,
        nextEl: navigationNextRef.current,
      }}
      onSwiper={(swiper) => {
        // Delay execution for the refs to be defined
        setTimeout(() => {
          // Override prevEl & nextEl now that refs are defined
          swiper.params.navigation.prevEl = navigationPrevRef.current
          swiper.params.navigation.nextEl = navigationNextRef.current

          // Re-init navigation
          swiper.navigation.destroy()
          swiper.navigation.init()
          swiper.navigation.update()
        })
      }}
    >
      <SwiperSlide>slide 1</SwiperSlide>
      <SwiperSlide>slide 2</SwiperSlide>
      <div ref={navigationPrevRef} />
      <div ref={navigationNextRef} />
    </Swiper>
  )
}
4个回答

我想我解决了这个问题,我也遇到了同样的问题,但最后,让我们开始吧

 1. import SwiperCore, { Navigation} from 'swiper'
 2. SwiperCore.use([Navigation])
 3. i will use your exmaple:     

    const MySwiper = () => {
      const navigationPrevRef = React.useRef(null)
      const navigationNextRef = React.useRef(null)
      return (
        <Swiper
          navigation={{
            prevEl: navigationPrevRef.current,
            nextEl: navigationNextRef.current,
          }}
         onBeforeInit={{
              swiper.params.navigation.prevEl = navigationPrevRef.current;
              swiper.params.navigation.nextEl = navigationNextRef.current;
         }}
        >
          <SwiperSlide>slide 1</SwiperSlide>
          <SwiperSlide>slide 2</SwiperSlide>
          <div ref={navigationPrevRef} />
          <div ref={navigationNextRef} />
        </Swiper>
      )
    }

就是这样,所以如果您检查 Swiper duc 有一个仅适用于 API 的页面,您可以在其中找到讨论 swiper 提供的事件的部分,无论如何我希望这是有帮助的

在 Swiper v6.2.0 中直接传递 refs 显然是不可能的。

我也为任何最终在这里图书馆作者回答的人创建了一个 Github 问题。 https://github.com/nolimits4web/swiper/issues/3855

只需注意 onBeforeInit 到胺 D 样本中的小错误。

更正的代码:

const MySwiper = () => {
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)
  return (
    <Swiper
      navigation={{
        prevEl: navigationPrevRef.current,
        nextEl: navigationNextRef.current,
      }}
     onBeforeInit={(swiper) => {
          swiper.params.navigation.prevEl = navigationPrevRef.current;
          swiper.params.navigation.nextEl = navigationNextRef.current;
     }}
    >
      <SwiperSlide>slide 1</SwiperSlide>
      <SwiperSlide>slide 2</SwiperSlide>
      <div ref={navigationPrevRef} />
      <div ref={navigationNextRef} />
    </Swiper>
  )
}

根据前面的答案,以下是完整的代码。这可能会帮助您根据需要实施。

import React from "react";
import SwiperCore, { Navigation } from 'swiper';
import { Swiper, SwiperSlide } from "swiper/react";

SwiperCore.use([Navigation]);

const MySwiper = () => {
      const navigationPrevRef = React.useRef(null)
      const navigationNextRef = React.useRef(null)
      return (
        <Swiper
          navigation={{
            prevEl: navigationPrevRef.current,
            nextEl: navigationNextRef.current,
          }}
         setTimeout(() => {
          // Override prevEl & nextEl now that refs are defined
          swiper.params.navigation.prevEl = navigationPrevRef.current
          swiper.params.navigation.nextEl = navigationNextRef.current

          // Re-init navigation
          swiper.navigation.destroy()
          swiper.navigation.init()
          swiper.navigation.update()
        })
        >
          <SwiperSlide>slide 1</SwiperSlide>
          <SwiperSlide>slide 2</SwiperSlide>
          <div ref={navigationPrevRef} />
          <div ref={navigationNextRef} />
        </Swiper>
      )
    }

const App = () => (
  <div>
    <MySwiper className="mySwiper1" />
    <MySwiper className="mySwiper2" />
  </div>
)

ReactDOM.render(<App/>, document.getElementById('root'));