在 React 中构建简单的时间线

2025-05-25

在 React 中构建简单的时间线

如今,许多作品集网站都提供时间轴功能,其用途多种多样。你可以展示你的工作和教育经历、过往项目、博客文章以及其他所有可以融入时间轴的内容。你可以自行构建时间轴,也可以使用一些现成的插件,这些插件设置简单,而且开箱即用,效果非常出色。我将向你展示其中一个插件,并举例说明如何使用一些模拟数据生成所有元素,让你很快就能拥有自己的时间轴。

如果您更喜欢视频版本,您可以在 Youtube 上观看我制作它:

我通过在工作文件夹中运行 create-react-app 命令启动了一个新的 React 应用程序。

create-react-app timeline
Enter fullscreen mode Exit fullscreen mode

我们的计划是构建一个组件,它可以提取我们所有的工作和教育经历,包括职称、日期、描述等,并以编程方式创建时间线。我将使用一个单独的 JavaScript 文件来模拟数据库,该文件会导出一个包含所有数据的对象数组。您可以使用任何现有的 JavaScript 文件,也可以直接使用我的。timelineElements.js 文件如下所示:

let timelineElements = [
  {
    id: 1,
    title: "Frontend Developer",
    location: "Dragontail, Ascana",
    description:
      "Converting data to a graphical interface, through the use of HTML, CSS, and JavaScript, so that users can view and interact with that data.",
    buttonText: "View Frontend Projects",
    date: "August 2016 - present",
    icon: "work",
  },
  {
    id: 2,
    title: "Backend Developer",
    location: "Skystead, Craonia",
    description:
      "Working hand-in-hand with front-end developers by providing the outward facing web application elements server-side logic. Creating the logic to make the web app function properly, and accomplishing this through the use of server-side scripting languages.",
    buttonText: "View Backend Projects",
    date: "June 2013 - August 2016",
    icon: "work",
  },
  {
    id: 3,
    title: "Quality Assurance Engineer",
    location: "South Warren, Geshington",
    description:
      "Assessing the quality of specifications and technical design documents in order to ensure timely, relevant and meaningful feedback.",
    buttonText: "Company Website",
    date: "September 2011 - June 2013",
    icon: "work",
  },
  {
    id: 4,
    title: "Oak Ridge College",
    location: "South Warren, Geshington",
    description:
      "Online Course in Magical Beasts and Wonders of the World - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec scelerisque sagittis tellus, non ultrices lacus tempus vel.",
    buttonText: "Course Certificate",
    date: "September 2011",
    icon: "school",
  },
  {
    id: 5,
    title: "Hawking College",
    location: "Skystead, Craonia",
    description:
      "College - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec scelerisque sagittis tellus, non ultrices lacus tempus vel.",
    buttonText: "College Projects",
    date: "2007 - 2011",
    icon: "school",
  },
  {
    id: 6,
    title: "Marble Hills Grammar School",
    location: "Dragontail, Ascana",
    description:
      "Highschool - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec scelerisque sagittis tellus, non ultrices lacus tempus vel.",
    date: "2003 - 2007",
    icon: "school",
  },
]

export default timelineElements
Enter fullscreen mode Exit fullscreen mode

由于我们的数据将包含以前的工作和学校信息,因此我们需要两个单独的图标来显示。我在网上找到了几个 SVG 图标——“PC 显示器”用于工作,“大学帽子”用于教育。

我们还需要通过运行 npm 命令来安装时间线插件:

npm i react-vertical-timeline-component
Enter fullscreen mode Exit fullscreen mode

由于这是一个简单的项目,我将把所有内容都放在 App 组件中,除了 CSS 文件,CSS 文件将放在单独的 App.css 文件中。首先,我们需要导入插件、数据文件和我们的 SVG 图标。

import "./App.css"
import { ReactComponent as WorkIcon } from "./work.svg"
import { ReactComponent as SchoolIcon } from "./school.svg"

import timelineElements from "./timelineElements"

import {
  VerticalTimeline,
  VerticalTimelineElement,
} from "react-vertical-timeline-component"

import "react-vertical-timeline-component/style.min.css"

function App() {
  return (
    <div>
      <h1 className="title">Timeline</h1>
      <VerticalTimeline></VerticalTimeline>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

我们需要将数据文件映射到时间线元素中。

import "./App.css"
import { ReactComponent as WorkIcon } from "./work.svg"
import { ReactComponent as SchoolIcon } from "./school.svg"

import timelineElements from "./timelineElements"

import {
  VerticalTimeline,
  VerticalTimelineElement,
} from "react-vertical-timeline-component"

import "react-vertical-timeline-component/style.min.css"

function App() {
  return (
    <div>
      <h1 className="title">Timeline</h1>
      <VerticalTimeline>
        {timelineElements.map(element => {
          return (
            <VerticalTimelineElement
              key={element.key}
              date={element.date}
              dateClassName="date"
            >
              <h3 className="vertical-timeline-element-title">
                {element.title}
              </h3>
              <h5 className="vertical-timeline-element-subtitle">
                {element.location}
              </h5>
              <p id="description">{element.description}</p>
            </VerticalTimelineElement>
          )
        })}
      </VerticalTimeline>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

时间线插件为我们提供了一个为图标样式设置对象的选项,我们可以使用它根据文件中定义的图标类型设置具有不同样式的不同图标。

import "./App.css"
import { ReactComponent as WorkIcon } from "./work.svg"
import { ReactComponent as SchoolIcon } from "./school.svg"

import timelineElements from "./timelineElements"

import {
  VerticalTimeline,
  VerticalTimelineElement,
} from "react-vertical-timeline-component"

import "react-vertical-timeline-component/style.min.css"

function App() {
  let workIconStyles = { background: "#06D6A0" }
  let schoolIconStyles = { background: "#f9c74f" }

  return (
    <div>
      <h1 className="title">Timeline</h1>
      <VerticalTimeline>
        {timelineElements.map(element => {
          let isWorkIcon = element.icon === "work"

          return (
            <VerticalTimelineElement
              key={element.key}
              date={element.date}
              dateClassName="date"
              iconStyle={isWorkIcon ? workIconStyles : schoolIconStyles}
              icon={isWorkIcon ? <WorkIcon /> : <SchoolIcon />}
            >
              <h3 className="vertical-timeline-element-title">
                {element.title}
              </h3>
              <h5 className="vertical-timeline-element-subtitle">
                {element.location}
              </h5>
              <p id="description">{element.description}</p>
            </VerticalTimelineElement>
          )
        })}
      </VerticalTimeline>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

我们还可以为每个时间线元素设置一个自定义按钮,并且可以根据时间线元素类型应用不同的样式。

import "./App.css"
import { ReactComponent as WorkIcon } from "./work.svg"
import { ReactComponent as SchoolIcon } from "./school.svg"

import timelineElements from "./timelineElements"

import {
  VerticalTimeline,
  VerticalTimelineElement,
} from "react-vertical-timeline-component"

import "react-vertical-timeline-component/style.min.css"

function App() {
  let workIconStyles = { background: "#06D6A0" }
  let schoolIconStyles = { background: "#f9c74f" }

  return (
    <div>
      <h1 className="title">Timeline</h1>
      <VerticalTimeline>
        {timelineElements.map(element => {
          let isWorkIcon = element.icon === "work"
          let showButton =
            element.buttonText !== undefined &&
            element.buttonText !== null &&
            element.buttonText !== ""

          return (
            <VerticalTimelineElement
              key={element.key}
              date={element.date}
              dateClassName="date"
              iconStyle={isWorkIcon ? workIconStyles : schoolIconStyles}
              icon={isWorkIcon ? <WorkIcon /> : <SchoolIcon />}
            >
              <h3 className="vertical-timeline-element-title">
                {element.title}
              </h3>
              <h5 className="vertical-timeline-element-subtitle">
                {element.location}
              </h5>
              <p id="description">{element.description}</p>
              {showButton && (
                <a
                  className={`button ${
                    isWorkIcon ? "workButton" : "schoolButton"
                  }`}
                  href="/"
                >
                  {element.buttonText}
                </a>
              )}
            </VerticalTimelineElement>
          )
        })}
      </VerticalTimeline>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

这样我们的组件就完成了,我们可以转到 App.css 文件并应用其余样式。

body {
  background: #3da3d5;
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
  color: rgb(53, 53, 53);
}

.title {
  font-size: 15em;
  text-align: center;
  font-family: "Bebas Neue", sans-serif;
}

h3 {
  padding-top: 0.25em;
}

.vertical-timeline-element-content {
  box-shadow: 0 0.25em 0.5em 0 rgba(0, 0, 0, 0.25), 0 0.4em 1.25em 0 rgba(0, 0, 0, 0.15) !important;
  padding: 2em 3em !important;
}

.date {
  color: rgb(201, 251, 255);
}

#description {
  margin: 1.5em 0 2em 0;
}

.button {
  text-decoration: none;
  padding: 0.5em 1em;
  border-radius: 5px;
  color: white;
}

.workButton {
  background-color: #06d6a0;
}

.workButton:hover {
  background-color: #0ac593;
}

.schoolButton {
  background-color: #f9c74f;
}

.schoolButton:hover {
  background-color: #f3bc3c;
}
Enter fullscreen mode Exit fullscreen mode

我把日期文本的颜色设为非常浅的蓝色,但一旦切换到宽度小于 1700px 的屏幕,就会变得有点难以阅读。我们可以通过使用简单的媒体规则来解决这个问题,以及它尴尬的定位。

@media only screen and (max-width: 1700px) {
  .vertical-timeline-element-date {
    display: block !important;
    float: none !important;
    color: rgb(44, 44, 44);
    margin-top: 1.5em;
  }
}
Enter fullscreen mode Exit fullscreen mode

如果您成功完成操作,现在应该已经拥有一个简单但功能多样的时间线原型。该插件本身允许您添加和切换许多不同的功能。完整文档请查看其官方 npm 页面

该项目的演示版本可以在CodeSandbox找到

您可以在我的GitHub上找到完整的代码

如果您有任何问题或意见,可以通过TwitterInstagram联系我,我还会在那里发布有趣的代码花絮和设计。

我还定期将 React 和 Web 开发教程上传到 Youtube,所以如果您感兴趣的话,请随时通过订阅我的频道来支持我。

文章来源:https://dev.to/alekswritescode/build-simple-timeline-in-react-474c
PREV
Node.js 最佳实践列表(2021 年 7 月)Node.js 最佳实践 1. 项目结构实践 2. 错误处理实践 3. 代码风格实践 4. 测试和整体质量实践 5. 投入生产实践 6. 安全最佳实践 7. 草案:性能最佳实践 8. Docker 最佳实践
NEXT
掌握 Google 的使用技巧至关重要。你知道该如何操作吗?明确阶段 站点搜索 多个关键词 排除关键词 相关关键词 通配符 时间范围 文件类型 高级搜索。