如何用React.js和Bootstrap构建动画式的登录路线

375 阅读12分钟

用React.js和Bootstrap构建动画签到路线

创建独特的用户界面(UI)需要创造力和对现代设计和造型框架的掌握。由于网站中浏览量最大的部分之一是签到页面,因此前端Web开发人员有责任创建一个有吸引力的页面。

这是为了促进和鼓励用户注册。在建立令人惊叹的网页(如签到页)时,React.js和Bootstrap与普通的CSS可以成为一个强大的组合。

在本教程中,我们将通过使用React.js构建动画签到路线所需的必要步骤和软件包。我们还将深入分析到一个vanilla CSS应用中,并添加动画和自定义组件。

主要收获

在本教程结束时,读者将了解如何。

  • 用React.js和bootstrap建立动画签到路线。
  • 在react应用中使用Reactstrap。
  • 开始使用React.js。
  • 用React.js和Bootstrap创建一个表单。
  • 用CSS和Bootstrap添加动画和定制。

前提条件

需要具备React.js、CSS和任何设计库(如Bootstrap)的基本知识,才能跟上并理解本教程。

教程概述

为了更好地理解和跟进,我们将把用React.js和bootstrap构建动画签到路线的任务分解为以下步骤。

第1步 - 开始使用React应用程序

React.js通过将整个设置react-app ,简化了应用程序的开发,只需一个命令即可。下面的命令将创建和设置一个新的react应用程序,所有需要的默认依赖都由React自动安装。

打开你的command terminal ,运行下面的命令。

npx create-react-app My-app

另外,对于yarn用户。

yarn create-react-app My-app

该操作可能需要一些时间来设置应用程序,以便后续开发。另外,请随意使用你希望的应用程序的名称。用你选择的任何名字替换 "My-app"。

注意React的命名惯例,以避免违反时可能出现的错误。

第2步 - 设置React应用程序

如果你在你喜欢的文本编辑器中打开应用程序,你会发现一些有用的文件,我们将设置这些文件以建立动画的签到和注册路线。让我们继续安装依赖项。

安装所需的依赖性

有几个依赖项,我们将添加到我们的react应用程序,以便React.js可以执行我们将实现的代码片段。

我们将安装以下依赖项。

  1. React-router-dom - 这个包使React.js能够在页面(路由)之间切换,而不会在这个过程中出现压力或错误。
  2. Reactstrap - 这个依赖项是一个根据React.js规范设计的修改的bootstrap包。这个包的使用将在本教程中详细讨论。
  3. React-date-picker - 我添加了这个包,因为它降低了获取日期信息的复杂性,例如出生日期、月份的哪一天等等。它提供了一个下拉菜单,其中的日、月、年都是现成的。
  4. Semantic-ui-react - 我们将需要在我们的页面上设置semantic-ui-react 图标。图标使网页更具描述性,而semantic-ui提供了许多现成的图标。

要安装上述软件包,请编辑package. json 文件,以包括如下所示的依赖项。

"dependencies": {
 "react-router-dom": "^5.2.0",
 "reactstrap": "8.7.1",
 "react-datepicker": "^3.7.0",
"semantic-ui-react": "^2.0.1",
},

完成之后,保存这些修改,再次打开command terminal ,然后运行下图所示的安装命令。

npm install

或者,对于yarn用户。

yarn add

这将开始安装过程。一旦完成,你的package. json 应该看起来像这样。

"dependencies": {
  "@testing-library/jest-dom": "^4.2.4",
  "@testing-library/react": "^9.5.0",
  "@testing-library/user-event": "^7.2.1",
  "classnames": "2.2.6",
  "react": "17.0.1",
  "react-datepicker": "^3.7.0",
  "reactstrap": "8.7.1",
  "react-dom": "17.0.1",
  "react-router-dom": "5.2.0",
  "react-scripts": "4.0.1",
  "reactstrap": "8.7.1",
"semantic-ui-react": "^2.0.1",
},

设置React路由器和路由(App.js)

我们将使用上面安装的 react-router-dom 包来创建路由。为了设置我们的应用程序所需的路由(注册和登录),我们需要通过实现下面的代码片断来修改App.js 文件。

import React from "react";
import { BrowserRouter as Router, Route, Switch   } from "react-router-dom";
import LoginPage from './LoginPage'
import RegisterPage from './RegisterPage'
export default function Routes() {

  return (
    <Router>
      <Switch>
        <Route exact path="/login" component={LoginPage} />
        <Route exact path="/register" component={RegisterPage} />
      </Switch>
    </Router>
  )
}

从上面的代码片断中,我们做了以下导入。

  • BrowserRouter as Router - 这是一个路由器实现,确保你的浏览器界面与URL同步。它还必须为它们包裹所有的组件和路由(页面)。
  • 路由 - 为了在一个页面的路径与所需的路径(URL)匹配时有条件地显示该页面,使用了路由组件。
  • 开关 - 开关组件防止两个路由被呈现。它通过渲染与位置相匹配的第一个路由来实现这一目的。

我们还导入了LoginPage RegisterPage ,不久将创建。

第3步 - 创建所需的组件

如前所述,我们将只创建2个路由组件。

  1. LoginPage组件
  2. 注册页组件

你可以根据你的需要创建和添加更多的页面。

LoginPage组件(LoginPage.js)

登录页面将使注册用户能够登录到该应用程序。该页面将由以下部分组成。

  • 表格
  • 按钮
  • 页面标题
  • 页面图像
  • 图标
  • 链接到新用户的注册页面。

src 文件夹中,创建一个LoginPage.js ,此后实现下面的代码片段。

import React from "react";
import { Button, Form} from "reactstrap";
import { Icon} from '"semantic-ui-react"'
import rocket from "./undraw_maker_launch_crhe.svg";
import { Link } from "react-router-dom/cjs/react-router-dom.min";

function Login() {
  return (
    <div className="container signMode">
      <div className="form-container">

          <div className="signin-signup">
            <Form className="sign-form sign-in-form ">
              <h2 className="form-title">Sign in</h2>
              <div className="input-field">
                <Icon name="user" />
                <input
                  type="text"
                  placeholder="Username"
                />
              </div>
              <div className="input-field">
                <Icon name="lock" />
                <input
                  type="password"
                  placeholder="Password"
                />
              </div>
              <Button type="submit" className="sign-up-button">
                LOGIN
              </Button>
            </Form>

          </div>
      </div>
      <div className="panel-container">
        <div className="panel left-panel">
          <div className="content">
            <h3>New here?</h3>
            <p>
              Let's get you started with a new account to join the community
            </p>
            <Link to="/register">
              <Button className="transparent" onClick={() => setActive(true)}>
                SIGN UP
              </Button>
            </Link>
          </div>
          <img src={rocket} className="image" alt="rocket" />
        </div>
      </div>
    </div>
  );
}

export default Login;

从上面的代码片段中,我们从之前安装的Reactstrap库中导入了FormButton 。我们还从react-router-dom 中导入了一个Link ,一旦用户点击它就会重定向到注册页面。

如前所述,React.js中网页之间的路由和导航是由react-router-dom 。然后,为了给我们的登录页面添加更多细节,我们添加了一些从semantic-ui-react 库中导入的图标。然后,我们添加了一些占位符和描述性文本。

你需要在src 文件夹中添加两张图片。请自由使用这些未画出的插图中的两张图片。此后我们分别导入到LoginPageRegisterPage 组件中,如上面的片段所示。

RegisterPage组件(RegisterPage.js)

RegisterPage 组件将像登录页面一样,但有一些不同之处。我们将为以下内容添加额外的表单输入字段。

  • 全名
  • 用户名
  • 电子邮件地址
  • 出生日期
  • 密码
  • 确认密码

为了创建注册页面,在src 文件夹中创建另一个文件RegisterPage.js 。一旦完成,继续下面的代码片断。

import React, {useState} from "react";
import { Button, Form} from "reactstrap";
import {Icon} from 'semantic-ui-react'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import play from "../images/undraw_press_play_bx2d.svg";
import { Link } from "react-router-dom/cjs/react-router-dom.min";

function Register() {
  const [next, setNext] = useState(false);
  const [startDate, setStartDate] = useState(null);

  return (
    <div className={`container ${active && `signMode`}`}>
      <div className="form-container">
          <div className="signin-signup">
            <Form
              className={`${next && `nextForm`}
              sign-form sign-up-form one `}
            >
              <h2 className="form-title">Sign Up</h2>
              <div className="input-field">
                <Icon name="user" />
                <input
                  type="text"
                  placeholder="Username"
                />
              </div>
              <div className="input-field">
                <Icon name="envelope" />
                <input
                  type="email"
                  placeholder="Email"
                />
              </div>

              <div className="input-field">
                <Icon name="calendar alternate outline" />
                <DatePicker
                  name="age"
                  onChange={(date) => setStartDate(date)}
                  placeholderText="Date of birth"
                  popperPlacement="top"
                  selected={startDate}
                />
              </div>
              <Button
                className="sign-up-button"
                onClick={() => setNext(true)}
              >
                NEXT
              </Button>
            </Form>

            <Form
              onSubmit={onSubmit}
              className={` ${
              next && `nextForm`}
              sign-form sign-up-form two `}
            >
              <h2 className="form-title">Continue</h2>
              <div className="input-field">
                <Icon name="lock" />
                <input
                  type="password"
                  placeholder="Password"
                />
              </div>
              <div className="input-field">
                <Icon name="lock" />
                <input
                  type="Password"
                  placeholder="Confirm Password"
                />
              </div>
              <h6>by signing up you have agreed to our terms and conditions</h6>
              <Button className="sign-up-button" type="submit">
                FINISH
              </Button>
            </Form>
          </div>
      </div>
      <div className="panel-container">
        <div className="panel right-panel">
          <div className="content">
            <h3>One of Us?</h3>
            <p>Continue from where you left off</p>
            <Link to="/login">
              <Button className="transparent" onClick={() => setActive(false)}>
                SIGN IN
              </Button>
            </Link>
          </div>
          <img src={play} className="image" alt="play image" />
        </div>
      </div>
    </div>
  );
}

export default Register;

我们来看看上面的代码片断。

我们做了以下工作。

  • 首先,我们用React的UseState 钩子创建了一个状态,有条件地显示包含密码字段的第二个表单。一旦第一个表单中所要求的信息被提供,这就完成了。
  • 我们导入了之前安装的DatePicker 包,使用户能够提供他们的出生日期。它需要一些参数,如占位符、位置、onchange ,等等,这些参数将决定下拉的行为。
  • 我们还为已经注册的用户添加了一个登录页面的链接,让他们可以登录。

这个代码段是非常基本和容易理解的,因为我们还没有添加表单处理器来接受和处理输入。一旦我们完成了登录和注册页面的设置,现在是时候为我们的组件添加动画、定制和样式了。

在我们进行样式设计之前,我们应该启动开发服务器,以便在浏览器上实时查看我们的应用程序。

启动React.js开发服务器

为了在浏览器窗口显示我们的应用程序,我们需要启动React开发服务器。这个操作很简单,容易实现。要启动服务器,打开command terminal ,运行下面的命令。

npm start

或者

yarn start

上面的命令应该可以启动开发。一旦完成,在你的默认浏览器(http://localhost:3000/)上应该打开一个新的浏览器窗口,显示该应用程序。现在让我们深入研究本教程的CSS部分。

设计和定制组件(App.css)的样式

在普通的CSS的帮助下,我们将为页面添加样式和动画。CSS可以用来执行许多造型操作,如响应性和动画。

为了定制我们的页面,在App.css 文件中,我们要实现下面的CSS片段。

.container {
  position: relative;
  width: 100%;
  min-height: 100vh;
  background: #fff;
  overflow: hidden;
}
.container .form-container {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 2%;
  left: 0;
}

.container::before {
  content: "";
  position: absolute;
  width: 2000px;
  height: 2000px;
  border-radius: 50%;
  background: linear-gradient(-45deg, #740374, #a807a8);
  top: -10%;
  right: 48%;
  transform: translateY(-50%);
  z-index: 6;
  transition: 1.8s ease-in-out;
}
.sign-form {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 0 5rem;
  overflow: hidden;
  grid-column: 1 / 2;
  grid-row: 1 / 2;
  transition: 0.5s 0.7s ease-in-out;
}
.sign-form.sign-in-form {
  z-index: 2;
}

.sign-form.sign-up-form {
  z-index: 1;
  opacity: 0;
}

本教程的大部分内容都围绕着CSS和reactstrap。从上面的片段中,我们针对containerClassName ,它包裹了其他所有的页面元素。我们调整了widthheight ,把position 改为relative 。还添加了一些background colors 和一个border radius

最重要的是,我们使用了一个带有紫色阴影的线性梯度作为背景。我们还为签到表格添加了一些样式,如:align-items,justify-content,paddings, 等等,如上图。我们将在我们的应用程序中添加更多的样式。

还是在App.css ,继续下面的CSS代码片断。

.sign-up-button {
  background: #b90fb9 !important;
  color: #fff !important;
  width: 100px !important;
  height: 41px !important;
}
.form-title {
  font-size: 2.2rem;
  color: #444;
  margin-bottom: 10px;
}
.input-field {
  max-width: 340px;
  width: 100%;
  height: 55px;
  background: #f0f0f0;
  margin: 10px 0;
  border-radius: 55px;
  display: grid;
  grid-template-columns: 15% 85%;
  padding: 0.4rem;
}
.input-field i {
  text-align: center;
  line-height: 45px;
  color: #acacac;
  font-size: 1.1rem;
}

.signin-signup {
  position: absolute;
  top: 50%;
  left: 75%;
  transform: translate(-50%, -50%);
  width: 50%;
  height: fit-content;
  display: grid;
  grid-template-columns: 1fr;
  z-index: 5;
  transition: 1s 0.9s ease-in-out;
}

.sign-up-form .one {
  z-index: 2;
}
.sign-up-form .two {
  z-index: 1;
  opacity: 0;
}
.panel-container {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.panel {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: space-around;
  text-align: center;
  z-index: 7;
}
.panel .content {
  color: #fff;
  transition: 0.9s 0.6s ease-in-out;
}

.transparent {
  margin: 0;
  background: none !important;
  color: #fff !important;
  border: 2px solid #fff !important;
  width: 130px !important;
  height: 41px !important;
  font-weight: 600 !important;
  font-size: 0.8rem !important;
}
.left-panel {
  pointer-events: all;
  padding: 3rem 17% 2rem 12%;
}
.right-panel {
  pointer-events: none;
  padding: 3rem 12% 2rem 17%;
}
.image {
  width: 100%;
  transition: 1.1s 0.4s ease-in-out;
}
.right-panel .content,
.right-panel .image {
  transform: translateX(800px);
}

我们仍然针对我们分配给组件元素的各种ClassName ,并为它们添加样式。你应该注意,我们在一些样式中添加了!important 标志,以覆盖默认的Reactstrap样式。如果没有!important 标志,我们的样式将不会生效。

现在,让我们把动画和转换添加到我们的页面。要做到这一点,还是在App.css ,继续下面的CSS代码片段。

/* Animation */
.container.signMode::before {
  transform: translate(100%, -50%);
  right: 52%;
}
.container.signMode .left-panel .image,
.container.signMode .left-panel .content {
  transform: translateX(-800px);
}

.container.signMode .right-panel .content,
.container.signMode .right-panel .image {
  transform: translateX(0px);
}
.container.signMode .left-panel {
  pointer-events: none;
}
.container.signMode .right-panel {
  pointer-events: all;
}
.container.signMode .signin-signup {
  left: 25%;
}
.container.signMode form.sign-in-form {
  z-index: 1;
  opacity: 0;
}

.container.signMode form.sign-up-form.one,
.container.signMode form.nextForm.sign-up-form.two {
  z-index: 2;
  opacity: 1;
}
.container.signMode form.sign-up-form.two {
  z-index: 1;
  opacity: 0;
}
.sign-in-form {
  transition: 1.5s 0.5 ease-in-out !important;
}
.sign-up-form.one {
  transition: 0.5s 0.6s ease-in-out !important;
}
.sign-up-form.two {
  transition: 1.5s 0.5 ease-in-out !important;
}
.nextForm.two {
  transform: translateX(0);
}

.nextForm.one {
  transform: translateX(-800px);
}

从上面的代码片段中,我们将CSStransformation 添加到容器classNames 。这样,当用户点击按钮时,就可以更平滑地左右过渡。我们还添加了一些pointer-events ,以便每次在每个面板上启用和禁用一些点击事件。

然后,我们添加了1的z-index ,以确保没有任何元素位于我们的表单之上,并且它在任何时候都是可见的。在这一步的最后一节,我们将为我们的页面添加一些响应性,以确保它在所有的屏幕尺寸下都保持可见和整洁。要做到这一点,还是在App.css ,我们实现下面的代码片段。

/* Responsiveness */
@media (max-width: 870px) {
  .container {
    min-height: 800px;
    height: 100vh;
  }
  .container::before {
    width: 1500px;
    height: 1500px;
    left: 30%;
    bottom: 70%;
    transform: translateX(-50%);
    right: initial;
    top: initial;
    transition: 2s ease-in-out;
  }
  .signin-signup {
    width: 100%;
    left: 50%;
    top: 95%;
    transform: translate(-50%, -100%);
    transition: 1s 0.8s ease-in-out;
  }
  .panel-container {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 2fr 1fr;
  }
  .panel {
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    padding: 2.5rem 8%;
  }
  .transparent {
    width: 110px !important;
    height: 35px !important;
    font-size: 0.7rem !important;
  }
  .panel .content {
    padding-right: 15%;
    transition: 0.9s 0.8s ease-in-out;
  }
  .image {
    width: 200px;
    transition: 0.9s 0.6s ease-in-out;
  }
  .left-panel {
    grid-row: 1 / 2;
  }
  .right-panel {
    grid-row: 3 / 4;
  }
  .right-panel .content,
  .right-panel .image {
    transform: translateY(300px);
  }
  .container.signMode::before {
    transform: translate(-50%, 100%);
    bottom: 29%;
    right: initial;
  }
  .container.signMode .left-panel .image,
  .container.signMode .left-panel .content {
    transform: translateY(-300px);
  }
  .container.signMode .signin-signup {
    top: 0;
    transform: translate(-50%, 0);
    left: 50%;
  }
}
@media (max-width: 570px) {
  .sign-form {
    padding: 0 1.5rem;
  }
  .image {
    display: none;
  }
  .panel .content {
    padding: 0.5rem 1rem;
  }
  .container::before {
    bottom: 72%;
    left: 50%;
  }
  .container.signMode::before {
    bottom: 20%;
    left: 50%;
  }
}

从上面的代码片段中,我们使用了一些CSS@media 查询来为我们的页面添加响应性。我们还使图像在小屏幕上隐藏起来。CSS代码段基本上是不言自明的,不需要深入解释。

一旦你正确地实现了每个CSS块,花点时间观察你的浏览器窗口的变化,以获得更好的理解。你也可以从浏览器中检查每个元素和类dev-tools

总结

在这篇文章中,我们用React.js、Reactstrap和vanilla CSS创建并设计了登录和注册页面。我们还经历了为网站或博客建立好看的登录路线所需的页面元素。