极客园PC-第2章 登录

项目功能 - 登录

功能如下:

  1. 搭建登录页面结构
  2. 登录表单校验
  3. 登录逻辑
  4. 封装处理 token、axios 的工具函数
  5. 登录访问控制

基本结构

  • Card组件的使用
import { Card } from 'antd'

class Login extends Component {
  render() {
    return (
      <div className="login">
        <Card className="login-container">
          <p>Card content</p>
          <p>Card content</p>
          <p>Card content</p>
        </Card>
      </div>
    )
  }
}

  • 准备样式src/pages/Login/index.css
.login {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  background-image: url(../../assets/login.png);
}

.login-container {
  width: 440px;
  height: 360px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

  • 准备logo
+ import logo from '../../assets/logo.png'
class Login extends Component {
  render() {
    return (
      <div className="login">
        <Card className="login-container">
+          <img className="login-logo" src={logo} alt="" />
        </Card>
      </div>
    )
  }
}
  • 准备logo的样式
.login-logo {
  width: 200px;
  height: 60px;
  display: block;
  margin: 0 auto 20px;
}

绝对路径的使用

{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}
  • 使用绝对路径
import logo from 'assets/logo.png'

相当于
'src/assets/logo.png'
  • 重启项目

sass的使用

在react脚手架中已经有了sass的配置,因此只需要安装sass的依赖包,就可以直接使用sass了

  • 安装sass依赖包
yarn add sass -D
  • index.css改成index.scss
  • 导入index.scss文件

注意:如果使用了scss,scss中使用图片的绝对路径的时候需要加上~

background-image: url(~assets/login.png);

登录表单的使用

根据antd的表单组件进行修改https://ant.design/components/form-cn/#API

class Login extends Component {
  render() {
    return (
      <div className="login">
        <Card className="login-container">
          <img className="login-logo" src={logo} alt="" />
          {/* 表单 */}
          <Form name="basic">
            <Form.Item name="username">
              <Input placeholder="请输入手机号" />
            </Form.Item>

            <Form.Item name="password">
              <Input placeholder="请输入验证码" />
            </Form.Item>

            <Form.Item name="remember" valuePropName="checked">
              <Checkbox>我已阅读并同意[用户协议]和[隐私条款]</Checkbox>
            </Form.Item>

            <Form.Item>
              <Button type="primary" htmlType="submit" block>
                登录
              </Button>
            </Form.Item>
          </Form>
        </Card>
      </div>
    )
  }
}
  • 调整表单控件的大小
<Form name="basic" size="large">
  • 设置选中后的样式
.ant-checkbox-wrapper-checked span {
  color: #1890ff;
}

登录表单校验

<Form.Item
  name="username"
  rules={[
    {
      pattern: /^1[3-9]\d{9}$/,
      message: '手机号码格式不对',
    },
    { required: true, message: '请输入手机号' },
  ]}
>
  <Input placeholder="请输入手机号" />
</Form.Item>

<Form.Item
  name="password"
  rules={[
    {
      pattern: /^\d{6}$/,
      message: '验证码格式不对',
    },
    { required: true, message: '请输入验证码' },
  ]}
>
  <Input placeholder="请输入验证码" />
</Form.Item>

<Form.Item
  name="remember"
  valuePropName="checked"
  rules={[{ required: true, message: '请阅读协议' }]}
>
  <Checkbox>我已阅读并同意[用户协议]和[隐私条款]</Checkbox>
</Form.Item>

收集表单数据

  • 给表单注册事件
<Form
  size="large"
  validateTrigger={['onChange', 'onBlur']}
  onFinish={this.onFinish}
>
  • 提供事件处理函数
onFinish = (values) => {
  console.log(values)
}
  • 修改name属性
<Form.Item
+  name="mobile"
  rules={[
    {
      pattern: /^1[3-9]\d{9}$/,
      message: '手机号码格式不对',
    },
    { required: true, message: '请输入手机号' },
  ]}
>
  <Input placeholder="请输入手机号" />
</Form.Item>

<Form.Item
+  name="code"
  rules={[
    {
      pattern: /^\d{6}$/,
      message: '验证码格式不对',
    },
    { required: true, message: '请输入验证码' },
  ]}
>
  <Input placeholder="请输入验证码" />
</Form.Item>

<Form.Item
+  name="agree"
  valuePropName="checked"
  rules={[{ required: true, message: '请阅读协议' }]}
>
  <Checkbox>我已阅读并同意[用户协议]和[隐私条款]</Checkbox>
</Form.Item>

设置 默认值

<Form
  name="basic"
  size="large"
  onFinish={this.login}
  initialValues={{
    agree: true,
    mobile: '13811111111',
    code: '246810',
  }}
>

封装axios 的工具函数

  • 安装axios
yarn add axios
  • 新建文件utils/request.js
import axios from 'axios'

const instance = axios.create({
  baseURL: 'http://geek.itheima.net/',
  timeout: 5000,
})

// 请求拦截器
instance.interceptors.request.use(
  function (config) {
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 响应拦截器
instance.interceptors.response.use(
  function (response) {
    return response.data
  },
  function (error) {
    return Promise.reject(error)
  }
)

export default instance

  • 测试

api封装

  • 新建文件 src/api/user.js
import request from 'utils/request'

/**
 * 登录请求,用于用户登录
 * @param {string} mobile 手机号
 * @param {string} code 验证码
 * @returns Promise
 */
export const login = (mobile, code) => {
  return request({
    method: 'POST',
    url: '/authorizations',
    data: {
      mobile,
      code,
    },
  })
}
  • 发送请求进行登录
submit = async (values) => {
  const { mobile, code } = values
  try {
    const res = await login(mobile, code)
    // 存储token
    localStorage.setItem('itcast_geek_pc', res.data.token)
    // 跳转到首页
    this.props.history.push('/home')
    alert('登录成功')
  } catch (err) {
    alert(err.response.data.message)
  }
}

消息提示组件的使用

submit = async (values) => {
  const { mobile, code } = values
  try {
    const res = await login(mobile, code)
    // 存储token
    localStorage.setItem('itcast_geek_pc', res.data.token)
    // 跳转到首页
    this.props.history.push('/home')
    message.success('登录成功')
  } catch (err) {
    message.warning(err.response.data.message, 1)
  }
}
posted @ 2022-03-24 16:10  小沈曰  阅读(276)  评论(0编辑  收藏  举报