使用react-slider的React滑块教程

1,757 阅读10分钟

滑块是网络和移动应用中最常见的UI元素之一。它用于选择一个数值或数值范围,通过可视化连接到滑块的数据,提供更好的用户体验。

滑块在提供各种选择时很有帮助,比如选择一个特定的价格范围,跟踪包裹的运输,或完成一个表格。

在这篇文章中,我们将使用react-slider ,创建不同的滑块,这是一个React无头组件,易于构建和定制。

react-slider 组件

react-slider 是一个小型的、可访问的、与CSS无关的组件,可以帮助我们为React应用程序构建定制的滑块组件。它使用引擎盖下的渲染道具模式,为我们的应用程序提供一个无头UI。

让我们通过安装以下软件包开始使用react-slider 组件。

npm install react-slider

一旦我们安装了该软件包,并在我们的应用程序中渲染该组件。默认的滑块组件看起来就像下面这个滑块。

Default React slider GIF That Shows Marks Sliding Back And Forth

默认的React滑块

以后,我们可以使用这个滑块的默认代码来定制它。

<ReactSlider
    className="horizontal-slider"
    thumbClassName="example-thumb"
    trackClassName="example-track"
    renderThumb={(props, state) => <div {...props}>{state.valueNow}</div>}
/>

安装了滑块包后,我们可以查看组成滑块的三个主要部分:轨道、标记和拇指。

轨迹

轨道是连接滑块各部分的水平线。要自定义轨道,我们可以添加一个类名,如trackClassName ,或渲染一个自定义组件,如renderTrack 。使用类名,我们可以自定义轨道组件的样式。

但是,如果我们想对轨道进行控制,我们必须渲染一个自定义组件,并根据我们的要求来改变它。例如,渲染一个自定义组件控制更新用户,即一个值从X到Y的变化。

我们可以在此基础上编写我们自己的功能,比如更新一个父组件的状态。

下面是一个同时使用类名和渲染自定义组件的例子。

<ReactSlider
    className="horizontal-slider"
    thumbClassName="example-thumb"
    trackClassName="example-track"
    renderTrack={(props, state) => <div {...props} />}//custom track
/>

拇指

拇指是在轨道上滑动的元素,我们也可以用类名来定制它,或者使用render props方法渲染一个自定义组件。

A Slider With A Thumb Node With Arrow Pointing To The Thumb

标记

标记是滑块内部的一个步骤,它与轨道一起渲染,以更新进度或状态。当我们想建立一个基于进度的滑块时,它很有用。

这类似于一个进度条,但它有中间步骤。每一步都需要我们完成一个动作,然后再进行下一步。

这里,我们有一个垂直的滑块,每个步骤都有一个标记。

Final Vertical Slider

我们可以通过两种方式来定制标记:要么提供一个类名,要么使用渲染道具来渲染我们定制的标记组件。

到目前为止,我们已经涵盖了react-slider 的所有主要部分。现在,让我们通过一些常见的用例在React应用程序中实现它们。

在React中创建一个简单的滑块

要开始在React中用react-slider 组件建立一个滑块,在根文件夹中创建一个名为slider.js 的文件,并添加以下代码。

import ReactSlider from "react-slider";
const Slider = () => {
  return (
    <ReactSlider
      className="horizontal-slider"
      thumbClassName="example-thumb"
      trackClassName="example-track"
    />
  );
};
export default Slider;

在这里,我们提供了三个CSS类名,用于定制拇指、轨道和滑块。

.horizontal-slider {
  width: 100%;
  max-width: 500px;
  height: 100vh;
  margin: auto;
}
.example-thumb {
  cursor: pointer;
  position: absolute;
  z-index: 100;
  background: #ffffff;
  border: 5px solid #3774ff;
  border-radius: 100%;
  display: block;
  box-shadow: 0 0 2px 0 rgb(0 0 0 / 44%);
}
.example-thumb.active {
  background-color: grey;
}
.example-track {
  position: relative;
  background: #ddd;
}
.example-track.example-track-0 {
  background: #83a9ff;
}
.horizontal-slider .example-track {
  top: 20px;
  height: 4px;
}
.horizontal-slider .example-thumb {
  top: 12px;
  width: 10px;
  outline: none;
  height: 10px;
  line-height: 38px;
}

随着滑块的样式化,这里有两件重要的事情需要注意:example-thumbexample-track 类名只为轨道和拇指组件提供样式。

要为轨道从Mark 1到Mark 2设置样式,我们可以使用类名example-track.example-track-0 ,添加一个样式。我们将在创建一个垂直滑块时详细讨论这个问题。

随着定制的完成,我们完成了这个简单的滑块;在这里可以找到完整的代码和渲染

在React中创建一个垂直滑块

我们也可以使用react-slider 组件建立一个垂直滑块。垂直滑块经常显示进度。例如,许多电子商务网站使用垂直滑块来显示通过邮件交付的包裹的进展情况。

我们将建立的一个React垂直滑块的例子可以在这里找到

垂直滑块,像水平滑块一样,有三个组成部分:步骤、滑块和表单。

台阶

创建一个step.js 文件,并添加以下代码来渲染五个步骤中的每一个。从上面的图片中我们可以看到,我们有五个步骤的设计。因此,我们必须添加一个steps 数组,并在其中加入数值。基于活动元素,我们可以渲染相应的值。

import React from "react";
const steps = ["Step 1", "Step 2", "Step 3", "Step 4", "Step 5"];
const Step = ({ currentIndex }) => {
  return (
    <div className="steps-container">
      {steps.map((step, index) => {
        let color = currentIndex === index ? "#00d4ff" : "black";
        console.log("color", color);
        return (
          <div className="steps-item">
            <h3
              style={{
                margin: 0,
                color: color
              }}
            >
              {step}
            </h3>
          </div>
        );
      })}
    </div>
  );
};
export default Step;

在这里,我们有从父组件传来的currentIndex 道具。它持有滑块中当前活动元素的值。例如,如果第二个标记是活动的,currentIndex 是1。

在此基础上,我们可以从steps 数组中渲染和样式化该值。

垂直滑块

要添加一个垂直滑块,在根文件夹中添加Slider/index.js ,并添加以下代码。

import React from "react";
import ReactSlider from "react-slider";
import "../styles.css";
import "./slider.css";
const Slider = ({ onChange, currentIndex }) => {
  return (
    <ReactSlider
      className="vertical-slider"
      markClassName="example-mark"
      onChange={onChange}
      trackClassName="example-track"
      defaultValue={0}
      value={currentIndex}
      min={0}
      max={4}
      marks
      renderMark={(props) => {
        if (props.key < currentIndex) {
          props.className = "example-mark example-mark-completed";
        } else if (props.key === currentIndex) {
          props.className = "example-mark example-mark-active";
        }
        return <span {...props} />;
      }}
      orientation="vertical"
    />
  );
};
export default Slider;

然后我们可以导入ReactSlider ,并将一些属性传递给它。让我们来详细探讨一下它们。

className

className 这个道具决定了滑块是水平的还是垂直的,我们可以像这样来设计它。

.vertical-slider {
  height: 380px;
  width: 25%;
}

markClassName

定制每一步的标记可以通过markClassName 属性完成。我们可以使用className 来样式它,或者我们可以样式我们的自定义组件,并把它作为渲染道具传到react-slider 里面。

.example-mark {
  width: 8px;
  height: 8px;
  border: 2px solid rgb(0, 0, 0);
  background-color: rgb(255, 255, 255);
  cursor: pointer;
  border-radius: 50%;
  vertical-align: middle;
  margin: 0px calc(19px);
  bottom: calc(50% - 6px);
}
.example-mark.example-mark-active {
  border: 2px solid #00d4ff;
  background-color: rgb(255, 255, 255);
}
.example-mark.example-mark-completed {
  border: 2px solid rgb(255, 255, 255);
  background-color: #00d4ff;
} 

在这里,我们有三个类。

  • .example-mark 样式标记组件
  • example-mark-active 识别并样式化当前的活动标记
  • example-mark-completed 渲染已经被访问或完成的元素

trackClassName

我们可以使用滑块中的trackClassName 道具来定制和样式轨道。

.example-track {
  position: relative;
  background: #ddd;
}
.example-track.example-track-0 {
  background: #00d4ff;
}

请注意,example-track-0 确定每个指定轨道的样式。例如,如果我们有五个标记,我们可以使用track-0,track-1,track-2,track-3, 和track-4 来定制标记之间的每个轨道。

然后滑块就会呈现出这样的效果。

Styled Vertical Slider

其他垂直滑块属性包括。

  • onChange 每当我们改变或点击滑块中的标记时,都会调用一个函数
  • defaultValue 为第一次渲染指定一个活动标记的位置。
  • value 指定当前的索引值
  • Minmax 决定滑块的范围
  • marks 启用滑块的步骤标记。
  • renderMark 是一个渲染道具,用于定制标记。

在React中建立一个带有进度滑块的表单

在某些情况下,比如创建数字工作指示,我们可以建立一个带有进度滑块的表单。每一层都有一组用户必须完成的输入,而进度滑块显示用户在这个过程中的进度。

要开始创建一个表单,创建Form/index.js ,并添加以下代码。

import React from "react";
import FormElement from "./FormElement";
import "./style.css";
const formEls = ["Step 1", "Step 2", "Step 3", "Step 4", "Step 5"];
const Form = ({ currentIndex, handleNext, handleComplete }) => {
  return (
    <div className="form-container">
      <h3>{formEls[currentIndex]}</h3>
      {currentIndex === formEls.length - 1 ? (
        <FormElement
          value={"Complete"}
          onClick={() => handleComplete(currentIndex)}
        />
      ) : (
        <FormElement value={"Next"} onClick={() => handleNext(currentIndex)} />
      )}
    </div>
  );
};
export default Form;

该表单组件采取currentIndexhandleNexthandleComplete 道具来处理步骤。

在React中创建一个多级表单

使用滑块表单的另一种方式是通过开发一个使用多级表单的应用程序

由于多级表单使用水平滑块,我们必须为水平组件使用样式。像垂直滑块一样,我们有marks,min,max, 和value 的道具。因为这是基于表单的,所以我们不需要一个轨道。

让我们使用react-slider 和我们定制的、有风格的组件来实现一个多级表单。在多级表单上有两个主要组件:导航步骤和表单元素。

Multilevel Form Showing a Header With Different Progress Points And A Next and Back Button

我们必须管理组件状态中的当前索引,并根据该索引渲染表单元素。

下面的代码包含了我们上面看到的表单。

<ItemContainer>
    <Fragment>
      {tabs.map((tab, index) => {
        return (
          <FormItem active={state.value === index}>
            <h3>{tabs[index]}</h3>
            <br />
            <Button value={"Next"} onClick={onNext}>
              Next
            </Button>
            <Button value={"Back"} onClick={onPrevious}>
              Back
            </Button>
          </FormItem>
        );
      })}
    </Fragment>
</ItemContainer> 

表单的两个按钮,下一步后退,在组件状态中存储表单值。

const [state, setState] = useState({
    value: 0
  });
  const onNext = () => {
    setState({ ...state, value: state.value + 1 });
  };
  const onPrevious = () => {
    setState({ ...state, value: state.value - 1 });
  };

最后,我们有一个渲染自定义标记和拇指组件的滑块。react-slider 为我们提供了renderMarkrenderThumb 渲染道具,以渲染ReactSlider 中的自定义标记和拇指组件。

<ReactSlider
  className="horizontal-slider"
  marks
  min={0}
  max={4}
  value={state.value}
  trackClassName="example-track"
  renderMark={(props, state) => {
    return (
      <FormLevel>
        <FormLevelLabelContainer
          {...props}
          firstChild={true}
          active={false}
        >
          <FormLevelLabelText>{tabs[props.key]}</FormLevelLabelText>
        </FormLevelLabelContainer>
      </FormLevel>
    );
  }}
  renderThumb={(props, state) => {
    return (
      <FormLevel {...props} active={state.valueNow === state.value}>
        <FormLevelLabelContainer
          firstChild={true}
          active={state.valueNow === state.value}
        >
          <FormLevelLabelText>
            {tabs[state.valueNow]}
          </FormLevelLabelText>
        </FormLevelLabelContainer>
      </FormLevel>
    );
  }}
/>

对比React滑块组件

虽然这篇文章专注于react-slider ,在React中建立一个滑块,但也有其他选项可以使用。下面是对每一种的简要介绍,以及它们的优点和缺点。

Material-UI

Material-UI是一个流行的UI框架,其核心部分的压缩包大小约为300Kb,下载时间为13ms;其滑块包,material-ui-slider压缩包大小为26Kb,下载时间为1ms

Material UI对初学者友好的文档和在其内置编辑器中查看完整源代码的选项,使其在开发社区中很受欢迎。

然而,如果使用material-ui-slider ,它可能会增加一个应用程序的包的大小,而且自定义功能不能像react-slider 那样完全实现。

蚂蚁设计

Ant Design是一种UI设计语言和React UI库,也相当流行,但也有同样的问题,即捆绑的大小较重,最小为2.2Mb,这在构建滑块时可能造成问题。

另外,通过渲染道具使用自定义组件是不可能的

react-slider 的优势

react-slider 很容易定制,我们可以使用渲染道具模式渲染自定义组件。它也有最轻的包的大小,在最小化版本中为12Kb

总结

滑块是一个常见的React UI元素,用来显示一系列的数值,帮助用户快速选择一系列的选项。

虽然有很多库和框架来构建滑块,但react-slider 组件提供了可定制性,小的捆绑大小以获得高效的性能,以及高效的开发者体验。

但是,同样重要的是,如果你的产品或公司已经使用了一个框架或库,如Ant Design、Bootstrap或Material UI,那么使用这些各自库中的滑块组件会更容易。

这可以减少为一个应用程序管理多个库的开销。

The postReact slider tutorial using react-slider appearedfirst on LogRocketBlog.