继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

番茄闹钟三(登录注册页面)

慕仰4546411
关注TA
已关注
手记 21
粉丝 2
获赞 13

一. axios 配置需求

  • axios 文档
  • 配置 axios
    • 配置 appid 和 appsecret
    • 配置 gwt 验证的 gwt token

二. 安装 axios

  yarn add axios

三. 配置 axios

import axios from 'axios'
const appID = "PzutokfofqknrEzTaJUBkmJA"
const appSecret = "GUxobVHJT88pGFeDLtBpyT3D"

const instance = axios.create({
baseURL: 'https://gp-server.hunger-valley.com/',
headers: {
  't-app-id' : appID,
  't-app-secret': appSecret
}
});

四. 配置拦截器

  • interceptors 的作用是,比如发起请求的时候在参数上再加点东西。response 也是在 response 的时候先拿一点数据,然后再走到 axios,then 的那一步
// axios.ts
import axios from 'axios'

const appID = 'PzutokfofqknrEzTaJUBkmJA'
const appSecret = 'GUxobVHJT88pGFeDLtBpyT3D'

const instance = axios.create({
  baseURL: 'https://gp-server.hunger-valley.com/',
  headers: {
    't-app-id': appID,
    't-app-secret': appSecret
  }
})

instance.interceptors.request.use(function (config) {
  const xToken = localStorage.getItem('x-token')
  if (xToken) {
    config.headers['Authorization'] = `Bearer ${xToken}`
  }
  return config
}, function (error) {
  console.error(error)
  return Promise.reject(error)
})


instance.interceptors.response.use(function (response) {
  if (response.headers['x-token']) {
    localStorage.setItem('x-token', response.headers['x-token'])
  }
  return response
}, function (error) {
  return Promise.reject(error)
})

export default instance

五. 登录注册页面初步制作

import * as React from 'react';
import { Input,Icon,Button } from 'antd';
import axios from '../../../src/config/axios'

interface ISignUpState { // 如果不声明会报Property 'account' does not exist on type 'Readonly<{}>'.的错误
  account: string,
  password: string,
  passwordConformation: string
}

class SignUp extends React.Component<any,ISignUpState> { // 第一个参数声明prop的类型,第二个参数声明state的类型
  constructor(props:any){
    super(props)
    this.state = {
      account: '',
      password: '',
      passwordConformation: ''
    }
  }

  onChangeAccount = (e:any) => {
    this.setState({account: e.target.value})
  }

  onChangePassword = (e:any) => {
    this.setState({password: e.target.value})
  }

  onChangePasswordConformation = (e:any) => {
    this.setState({passwordConformation: e.target.value})
  }

  submit = async () => {
    const { account,password,passwordConformation } = this.state;
    try{
      await axios.post('sign_up/user',{
        account,
        password_confirmation:passwordConformation,
        password
      })
      console.log('成功')
    }catch (e) {
      throw new Error(e)
    }
  }

  public render() {
    const { account,password,passwordConformation } = this.state;
    return (
      <div className="SignUp">
        <Input
          placeholder="请输入你的用户名"
          prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
          value = {account}
          onChange={this.onChangeAccount}
        />
        <Input.Password value={password} placeholder="请输入密码" onChange={this.onChangePassword}/>
        <Input.Password value={passwordConformation} placeholder="请确认密码" onChange={this.onChangePasswordConformation}/>
        <Button onClick={this.submit}>注册</Button>
        </p>
      </div>
    )
  }
}

export default SignUp

六. Link 跳转页面的用法

//import {Link} from 'react-router-dom'
<Link to="/login">登录</Link>

七. 注册页的页面样式

#SignUp{
  max-width: 500px;
  margin: auto;
  padding: 50px 0;
  >*{
    margin: 10px 0;
  }
  >h1{
    text-align: center;
  }
  >.loginButton{
    width: 100%;
  }
}

八. 登录页的页面样式

#SignUp{
  max-width: 500px;
  margin: auto;
  padding: 50px 0;
  >*{
    margin: 10px 0;
  }
  >h1{
    text-align: center;
  }
  >.loginButton{
    width: 100%;
  }
}

九. 将 onChangeAccount 和 onChangePassword 抽成一个

interface ILoginState {
  account?: string,
  password?: string
}
onChange = (key: keyof ILoginState,value:string) => {
  this.setState({[key]:value})
}

十. 开始制作首页

到了首页检查用户登录信息,如果可以登录就直接登录,如果不能登录也就是token是过期的话,我们就跳转到登录页
// Index.ts
getMe = async () => {
    try{
      const response = await axios.get('me')
      this.setState({user: response.data})
    }catch (e) {
      console.error('获取用户失败')
      if(e.response.status === 401){
        this.props.history.push('/login')
      }
    }
  }

十一. 全局拦截,完成登出逻辑

// 服务器约定,凡是用户获取失败,返回状态都是401
instance.interceptors.response.use(function (response) {
  if (response.headers['x-token']) {
    localStorage.setItem('x-token', response.headers['x-token'])
  }
  return response
}, function (error) {
  window.location.href='/login' // 页面会再次跳转,粗暴的方式
  return Promise.reject(error)
})
// 通过react Router的方式,不会刷新
// 封装history.ts
import { createBrowserHistory } from 'history';
const history = createBrowserHistory()

export default  history

// 解决app.tsx没监听到组件的变化问题
import history from './config/history'
class Component extends React.Component  {
  public render(){
    return (
      <Router history={history}>
        <div>
          <Route exact={true} path="/" component={Index}/>
          <Route path="/login" component={Login} />
          <Route path="/signUp" component={SignUp} />
        </div>
      </Router>
    )
  }
}
export default Component
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP