【问题标题】:react.js antd carousel with arrowsreact.js antd 带箭头的轮播
【发布时间】:2017-10-22 04:35:50
【问题描述】:

我正在考虑使用 antd Caroseul,但我还没有看到创建上一个/下一个或暂停按钮的示例。

const { Carousel } = antd;

ReactDOM.render(
  <Carousel autoplay>
    <div><h3>1</h3></div>
    <div><h3>2</h3></div>
    <div><h3>3</h3></div>
    <div><h3>4</h3></div>
  </Carousel>
, document.getElementById('app'));

【问题讨论】:

  • 只需要在自动播放参数旁边添加“箭头”

标签: reactjs carousel antd


【解决方案1】:

在阅读https://ant.design/components/carousel/时,我滚动到底部,它说它正在使用https://github.com/akiran/react-slick

如果您向下滚动到 prop 表,您可以使用 nextArrowprevArrow,它将 React 元素作为值。

【讨论】:

  • 谢谢。 nextArrowprevArrowreact-slick.neostack.com/docs/api/#arrows 的 react-slick 文档上的 arrows 吗?我想左右箭头的 arrows 对象是相同的。在 AntD Carousel 代码中,arrows 应该放在哪里?
  • 请在此处显示一个道具类型示例以实现箭头。
【解决方案2】:
import React, { Component } from "react";
import { Carousel, Icon } from "antd";

export default class CarouselComponent extends Component {
  constructor(props) {
    super(props);
    this.next = this.next.bind(this);
    this.previous = this.previous.bind(this);
    this.carousel = React.createRef();
  }
  next() {
    this.carousel.next();
  }
  previous() {
    this.carousel.prev();
  }

  render() {
    const props = {
      dots: true,
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1
    };
    return (
      <div>
        <Icon type="left-circle" onClick={this.previous} />
        <Carousel ref={node => (this.carousel = node)} {...props}>
          <div>
            <h3>1</h3>
          </div>
          <div>
            <h3>2</h3>
          </div>
          <div>
            <h3>3</h3>
          </div>
          <div>
            <h3>4</h3>
          </div>
        </Carousel>
        <Icon type="right-circle" onClick={this.next} />
      </div>
    );
  }
}

【讨论】:

  • 请接受这个答案,以便其他开发者也知道答案。
【解决方案3】:

我正在使用 React Hooks。我刚找到结果。 示例如下:

function SampleNextArrow(props) {
    const { className, style, onClick } = props
    return (
        <div
        className={className}
        style={{ ...style, display: "block", background: "red" }}
        onClick={onClick}
        />
    )
}

function SamplePrevArrow(props) {
    const { className, style, onClick } = props
    return (
        <div
        className={className}
        style={{ ...style, display: "block", background: "green" }}
        onClick={onClick}
        />
    )
}

const settings = {
    dots: true,
    infinite: true,
    speed: 500,
    slidesToShow: 8,
    nextArrow: <SampleNextArrow />,
    prevArrow: <SamplePrevArrow />,
}

<Carousel {...settings} arrows={true} draggable={true}>
    {koompiApps.map((res, index) => {
        return (
        <Col xs={24} sm={24} md={24} lg={24} xl={24}>
            <div
            onClick={(e) => {
                setAppsKey(`${index + 1}`)
            }}
            >
            <center>
                <motion.div
                whileHover={{
                    scale: 1.1,
                    transition: { duration: 0.3 },
                }}
                whileTap={{ scale: 0.9 }}
                >
                <img
                    src={`${res.logo}`}
                    className="koompiApps "
                    alt={res.name}
                />
                <h4 className="appsName">{res.name}</h4>
                </motion.div>
            </center>
            </div>
        </Col>
        )
    })}
</Carousel>

结果:

【讨论】:

    【解决方案4】:

    只需按照以下代码: 使用 useRef 钩子并将 Ref 分配给 Carousel,然后通过 refrence 调用 next 和 prev 方法。

    import React, { useRef, Fragment } from "react";
    import { Carousel } from "antd";
    
    const MyCarousel = () => {
    const slider = useRef(null);
    
    return ( 
    <Fragment >
        <Button onClick={() => slider.current.next()}>next</Button>
        <Carousel ref={slider}>
            <div>Item 1</div>
            <div>Item 2</div>
            <div>Item 3</div>
        </Carousel>
        <Button onClick={() => slider.current.next()}>next</Button>
    </Fragment >
    )}
    

    【讨论】:

    • 对我来说这不起作用(我的程序崩溃了,因为它找不到函数)。所以我不得不声明 let slider = useRef(null) 。然后在轮播中我不得不像这样调用裁判:&lt;Carousel { ...settings } ref={ node =&gt; slider = node } ...
    • 这对我有用。最好的解决方案对我有用。
    【解决方案5】:

    首先:arrow 是一个有效的 Carousel 属性,它使箭头能够手动控制内容。 是antd的disabled by default

    您可以这样启用它:

    <Carousel arrows>
    //
    </Carousel>
    

    但您不会看到它们,因为 .ant-carousel .slick-prev.ant-carousel .slick-prev 的样式是透明的。

    此时您已经可以覆盖样式(例如display: block; background: red)。


    另一个选择是使用 React Slick 属性从 prop 内部控制样式,因为 antd 在 Carousel 组件的底层使用它。

    这是一个完整的组件示例:

    import React from 'react'
    import { Row, Col, Carousel } from 'antd'
    
    const contentStyle = {
      height: '160px',
      color: '#fff',
      lineHeight: '160px',
      textAlign: 'center',
      background: '#364d79'
    }
    
    // from https://react-slick.neostack.com/docs/example/custom-arrows
    const SampleNextArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{ ...style, display: 'block', background: 'red' }}
          onClick={onClick}
        />
      )
    }
    
    const SamplePrevArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{ ...style, display: 'block', background: 'green' }}
          onClick={onClick}
        />
      )
    }
    
    const settings = {
      nextArrow: <SampleNextArrow />,
      prevArrow: <SamplePrevArrow />
    }
    
    const CarouselArrows = () => {
      return (
        <>
          <Row justify="center">
            <Col span={16}>
              <Carousel arrows {...settings}>
                <div>
                  <h3 style={contentStyle}>1</h3>
                </div>
                <div>
                  <h3 style={contentStyle}>2</h3>
                </div>
                <div>
                  <h3 style={contentStyle}>3</h3>
                </div>
                <div>
                  <h3 style={contentStyle}>4</h3>
                </div>
              </Carousel>
            </Col>
          </Row>
        </>
      )
    }
    
    export default CarouselArrows
    


    有一个带有content 属性的::before 选择器有点搞砸了样式(您不能从内联样式中覆盖它)。 您可以利用它并将箭头功能更改为:

    const SampleNextArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{ ...style, display: 'block', background: 'red' }}
          onClick={onClick}
        />
      )
    }
    
    const SamplePrevArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{ ...style, display: 'block', background: 'green' }}
          onClick={onClick}
        />
      )
    }
    
    


    您可以覆盖默认的 antd 样式以删除 ::before 选择器并包含图标。

    在 LESS 文件中:

    .ant-carousel {
      .slick-next {
        &::before {
          content: '';
        }
      }
      .slick-prev { 
        &::before {
          content: '';
        }
      }
    }
    

    在您的组件中(暗示您正在使用上例中提供的组件):

    import { LeftOutlined, RightOutlined } from '@ant-design/icons'
    
    // ...
    
    const SampleNextArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{
            ...style,
            color: 'black',
            fontSize: '15px',
            lineHeight: '1.5715'
          }}
          onClick={onClick}
        >
          <RightOutlined />
        </div>
      )
    }
    
    const SamplePrevArrow = props => {
      const { className, style, onClick } = props
      return (
        <div
          className={className}
          style={{
            ...style,
            color: 'black',
            fontSize: '15px',
            lineHeight: '1.5715'
          }}
          onClick={onClick}
        >
          <LeftOutlined />
        </div>
      )
    }
    
    

    最后,想要的输出:

    【讨论】:

      【解决方案6】:

      将 prop arrows 设置为 true,应该会出现下一个和上一个箭头。但是你看不到,因为antd css设置为透明,鼠标悬停在上面就能感觉到。

      要使它们可见,您可以安装 slick-carousel npm,并导入 css:

      @import "~slick-carousel/slick/slick";
      @import "~slick-carousel/slick/slick-theme"; 
      

      然后将箭头css设置为:

      .ant-carousel .slick-arrow::before {
        font-size: 24px;
        font-family: 'slick';
        color: #000;
      }
      

      【讨论】:

        【解决方案7】:

        如果要添加箭头,可以使用Antd提供的箭头图标

        <Carousel arrows nextArrow={<ArrowRightOutlined />} prevArrow={<ArrowLeftOutlined/>}>
        
        

        由于箭头被 Antd css 隐藏了,你可以在你自己的 css 中用下面的代码覆盖它:

        .ant-carousel .slick-prev,
        .ant-carousel .slick-next {
          color: unset;
          font-size: unset;
        }
        
        .ant-carousel .slick-prev:hover,
        .ant-carousel .slick-next:hover,
        .ant-carousel .slick-prev:focus,
        .ant-carousel .slick-next:focus {
          color: unset;
        }
        
        

        【讨论】:

          【解决方案8】:

          当我们将arrows 传递给Carousel 时,它确实有效,但主要问题在于CSS,因为slick-prevslick-next 的默认font-size0px

          slick-prev::beforeslick-next::before 也存在同样的问题

          我可以推荐这个选项,它只会改变默认样式。 谢谢

           <Carousel autoplay arrows>
            <div>Test1</div>
            <div>Test2</div>
          </Carousel>
          .slick-arrow.slick-prev {
            font-size: 10px;
            
          }
          .ant-carousel .slick-prev::before {
              content: '<';
              display: block;
              position: relative;
              bottom: 20px;
              right: 3px;
              /* width: 100px; */
              font-size: 25px;
              color: gray;
              background-color: white;
              border: 2px solid gray;
              display: flex;
              justify-content: center;
              align-items: center;
              padding: 5px;
              border-radius: 50%;
              width: 33px;
              height: 33px;
             
          }
          .slick-arrow.slick-next {
            font-size: 10px;
          }
          .ant-carousel .slick-next::before {
            content: '>';
            display: block;
            position: relative;
            right: 3px;
            bottom: 20px;
            /* width: 100px; */
            font-size: 25px;
            color: gray;
            background-color: white;
            border: 2px solid gray;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 5px;
            border-radius: 50%;
            width: 33px;
            height: 33px;
          }
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

          【讨论】:

          • 感谢您的贡献。在 SO 上不鼓励仅代码转储。请考虑编辑以突出显示解决方案的关键部分并解释如何/为什么解决了 OP 的问题。随着时间的推移,大多数对高质量帖子的支持都会累积,因为未来的访问者会从您的帖子中学到一些东西,以应用于他们自己的编码问题。它还更好地体现了 SO 的使命,即成为协作、分享知识和学习的场所,而不是给人一种简单的免费编码服务的印象。
          猜你喜欢
          • 2017-12-26
          • 2014-11-06
          • 2023-03-19
          • 1970-01-01
          • 2017-11-06
          • 1970-01-01
          • 2021-08-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多