umijs + dva + request + js-cookie实现登录


*为了明年换工作,特地学习了react,所以使用umi搭建一个简易项目,学习下里面使用到的知识点,主要这次研究使用dva *
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,redux-saga 主要使用generator实现异步处理

dva链接: https://dvajs.com/guide/ link.
umijs链接:https://umijs.org/zh-CN/docs link.
umi-request链接: https://github.com/umijs/umi-request/link.
js-cookie链接: https://www.npmjs.com/package/js-cookielink.
使用umi创建项目我就不走步骤,直接上代码,里面有注解

一,在src下创建models文件夹,创建user.ts

下面展示一些 内联代码片

import { doLoign } from '@/service/login';
import { Subscription, Effect } from 'dva'
import { setCookie } from '@/utils/cookie'

interface UserModeType {
  namespace: String,
  state: {},
  reducers: {},
  effects: {},
  subscriptions: {
    setup: Subscription
  }
}

const UserMode: UserModeType = {
  namespace: 'users',
  // state: 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出
  state: {
    token: "",
    username: '',
  },
  // reducers: Action 处理器,处理同步动作,用来算出最新的 State
  reducers: {
    save(state, { payload: { token, username } }) {
      return { ...state, token, username };
    },
  },
  // effects,处理异步动作 call:执行异步函数 put:发出一个 Action,类似于 dispatch到reducers
  effects: {
    * fetch({ payload: { resolve, reject, userInfo } }, { call, put }) {
      try {
        const { data, code } = yield call(doLoign, { userInfo });
        setCookie("TOKEN", data.token)
        yield put({ type: 'save', payload: { token: data.token, username: userInfo.username } });
        resolve(code);
      }
      catch (error) {
        reject(error);
      }

    },
  },
  //改管理暂未用到,只是研究下用法
  // subscriptions: {
  //   setup({ dispatch, history }) {
  //     return history.listen(({ pathname, values }) => {
  //       if (pathname === '/user/login') {
  //         values = { userInfo: { name: 'admin', password: '111' } }
  //         dispatch({ type: 'fetch', payload: values });
  //       }
  //     });
  //   },
  // },
};
export default UserMode;

二,在pages下创建login文件下,组件使用函数创建

import { Form, Input, Button, Checkbox } from 'antd';
import { connect } from 'dva'
import React, { useState, useEffect } from 'react';
import { history } from 'umi';

const Demo = ({ users, dispatch }) => {
  // const [count, setCount] = useState(0);

  // 提交登录
  const onFinish = async (values: any) => {
    // 提交给dva 中的effects:Action 处理器
    new Promise((resolve, reject) => {
      dispatch({ type: 'users/fetch', payload: { resolve, reject, userInfo: values } });
    }).then((data) => {
      if (data === 'SUCCESS') { //跳转首页
        history.push('/home')
      }
    });

  };

  // forme表单异常
  const onFinishFailed = (errorInfo: any) => {
    console.log('Failed:', errorInfo);
  };
  // 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
  useEffect(() => {
    console.log(users, dispatch)
  }, []);
  return (
    <Form
      name="basic"
      labelCol={{
        span: 8,
      }}
      wrapperCol={{
        span: 16,
      }}
      initialValues={{
        remember: true,
      }}
      onFinish={onFinish}
      onFinishFailed={onFinishFailed}
      autoComplete="off"
    >
      <Form.Item
        label="Username"
        name="username"
        rules={[
          {
            required: true,
            message: 'Please input your username!',
          },
        ]}
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="Password"
        name="password"
        rules={[
          {
            required: true,
            message: 'Please input your password!',
          },
        ]}
      >
        <Input.Password />
      </Form.Item>

      <Form.Item
        name="remember"
        valuePropName="checked"
        wrapperCol={{
          offset: 8,
          span: 16,
        }}
      >
        <Checkbox>Remember me</Checkbox>
      </Form.Item>

      <Form.Item
        wrapperCol={{
          offset: 8,
          span: 16,
        }}
      >
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};
const mapStateToProps = ({ users }) => {
  return { users, }
}
export default connect(mapStateToProps)(Demo)

三,创建cookie管理文件,和request.ts,添加路由

import Cookies from 'js-cookie'

export function getCookie(CookieName: String) {
  return Cookies.get(CookieName)
}

export function setCookie(CookieName: String, CookieValue: any) {
  return Cookies.set(CookieName, CookieValue)
}

export function removeCookie(CookieName: String,) {
  return Cookies.remove(CookieName)
}

import request, { extend } from 'umi-request'
import { message } from 'antd'
import { getCookie } from '@/utils/cookie'
import { history } from 'umi';

// 请求拦截器
request.interceptors.request.use((url, options) => {

  // 如果接口是登录放行
  if (url === '/user/login') {
    return {
      url: `${url}`,
      options: { ...options, interceptors: true },
    };
  } else {
    if (getCookie('TOKEN') !== '' || getCookie('TOKEN') !== null) {
      message.error("TOKEN 丢失,请重新登录");
      history.push('/user/login');
      // 平阻断请求 (暂时未写)
      return {
        url: `${url}`,
        options: { ...options, interceptors: true },
      };
    } else {
      // 请求头添加token
      return {
        url: `${url}`,
        options: { ...options, interceptors: true },
      };
    }

  }
});
// 响应拦截器
request.interceptors.response.use(async response => {

  const data = await response.clone().json();
  console.log(data)
  // if (data.state && data.state === 200) {
  //   return response;
  // }
  return response;
});
export default request

export default [
  {
    path: '/user',
    layout: false,
    routes: [
      {
        name: 'login',
        path: '/user/login',
        component: '@/pages/login/index',
      },
    ],
  },
  {
    path: '/',
    component: '@/layouts/LayoutSide/index',
    routes: [
      {
        path: '/home', title: "首页", exact: false, component: '@/pages/home/index',
      },
    ],
  },
];

layouts不懂得可以看umi 关于layouts配置,希望给我在下下面评论,下章,研究request 阻断请求,以及动态路由实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值