极客园PC-第2章 登录


项目功能 - 登录

功能如下:

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

基本结构

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

class Login extends Component {
  render() {
    return (
      

Card content

Card content

Card content

) } }
  • 准备样式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 (
      
+
) } }
  • 准备logo的样式
.login-logo {
  width: 200px;
  height: 60px;
  display: block;
  margin: 0 auto 20px;
}

绝对路径的使用

  • 官网文档:https://facebook.github.io/create-react-app/docs/importing-a-component#absolute-imports
  • 在根目录新建jsconfig.json文件
  • 配置以下内容
{
  "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 (
      
{/* 表单 */}
我已阅读并同意[用户协议]和[隐私条款]
) } }
  • 调整表单控件的大小
  • 设置选中后的样式
.ant-checkbox-wrapper-checked span {
  color: #1890ff;
}

登录表单校验


  



  



  我已阅读并同意[用户协议]和[隐私条款]


收集表单数据

  • 给表单注册事件

  • 提供事件处理函数
onFinish = (values) => {
  console.log(values)
}
  • 修改name属性

  



  



  我已阅读并同意[用户协议]和[隐私条款]

设置 默认值


封装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)
  }
}