美文网首页
react之Ant Design Pro系列快速入门(二)--登

react之Ant Design Pro系列快速入门(二)--登

作者: 子木话 | 来源:发表于2019-10-05 09:57 被阅读0次

登录
在启动篇中加载全局路由时有一句代码如下,方法返回路径和对应的界面

const routerData = getRouterData(app);
路由配置对象

const routerConfig = {
     '/': {
     component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
     },
     
     '/dashboard/analysis': {
     component: dynamicWrapper(app, ['chart'], () => import('../routes/Dashboard/Analysis')),
     },
     '/dashboard/monitor': {
     component: dynamicWrapper(app, ['monitor'], () => import('../routes/Dashboard/Monitor')),
     },
     '/dashboard/workplace': {
     component: dynamicWrapper(app, ['project', 'activities', 'chart'], () =>
         import('../routes/Dashboard/Workplace')
     ),
     // hideInBreadcrumb: true,
     // name: '工作台',
     // authority: 'admin',
     },
     '/test/test': {
     component: dynamicWrapper(app, [], () =>
         import('../routes/test/NormalLoginForm')
     ),
     // hideInBreadcrumb: true,
     // name: '工作台',
     // authority: 'admin',
     },
     '/form/basic-form': {
     component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/BasicForm')),
     },
     '/form/step-form': {
     component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm')),
     },
     '/form/step-form/result': {
     name: '分步表单(完成)',
     component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step3')),
     },
     '/list/card-list': {
     component: dynamicWrapper(app, ['list'], () => import('../routes/List/CardList')),
     },
     '/list/search': {
     component: dynamicWrapper(app, ['list'], () => import('../routes/List/List')),
     },
     '/result/success': {
     component: dynamicWrapper(app, [], () => import('../routes/Result/Success')),
     },
     '/result/fail': {
     component: dynamicWrapper(app, [], () => import('../routes/Result/Error')),
     },
     '/exception/403': {
     component: dynamicWrapper(app, [], () => import('../routes/Exception/403')),
     },
     '/exception/404': {
     component: dynamicWrapper(app, [], () => import('../routes/Exception/404')),
     },
     '/exception/500': {
     component: dynamicWrapper(app, [], () => import('../routes/Exception/500')),
     },
     '/exception/trigger': {
     component: dynamicWrapper(app, ['error'], () =>
         import('../routes/Exception/triggerException')
     ),
     },
     '/user': {
     component: dynamicWrapper(app, [], () => import('../layouts/UserLayout')),
     },
     '/user/login': {
     component: dynamicWrapper(app, ['login'], () => import('../routes/User/Login')),
     },
     '/user/register': {
     component: dynamicWrapper(app, ['register'], () => import('../routes/User/Register')),
     },
     '/user/register-result': {
     component: dynamicWrapper(app, [], () => import('../routes/User/RegisterResult')),
     },
     // '/user/:id': {
     //   component: dynamicWrapper(app, [], () => import('../routes/User/SomeComponent')),
     // },
 };

根据默认路由/user/login找到对应的登录界面app/src/routes/User/Login.js

import React, { Component } from 'react';
 import { connect } from 'dva';
 import { Link } from 'dva/router';
 import { Checkbox, Alert, Icon } from 'antd';
 import Login from 'components/Login';
 import styles from './Login.less';
 
 const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login;
 // 此操作符连接命名空间为login的model层
 @connect(({ login, loading }) => ({
 login,
 submitting: loading.effects['login/login'],
 }))
 export default class LoginPage extends Component {
 state = {
     type: 'account',
     autoLogin: true,
 };
 
 onTabChange = type => {
     this.setState({ type });
 };
 
 handleSubmit = (err, values) => {
     const { type } = this.state;
     const { dispatch } = this.props;
     if (!err) {
     // 调用loigin命名空间下的login方法
     dispatch({
         type: 'login/login',
         payload: {
         ...values,
         type,
         },
     });
     }
 };
 
 changeAutoLogin = e => {
     this.setState({
     autoLogin: e.target.checked,
     });
 };
 
 renderMessage = content => {
     return <Alert style={{ marginBottom: 24 }} message={content} type="error" showIcon />;
 };
 // 登录界面,可以更改为自定义的UI
 render() {
     const { login, submitting } = this.props;
     const { type, autoLogin } = this.state;
     return (
     <div className={styles.main}>
         <Login defaultActiveKey={type} onTabChange={this.onTabChange} onSubmit={this.handleSubmit}>
         <Tab key="account" tab="账户密码登录">
             {login.status === 'error' &&
             login.type === 'account' &&
             !submitting &&
             this.renderMessage('账户或密码错误(admin/888888)')}
             <UserName name="userName" placeholder="admin/user" />
             <Password name="password" placeholder="888888/123456" />
         </Tab>
         <Tab key="mobile" tab="手机号登录">
             {login.status === 'error' &&
             login.type === 'mobile' &&
             !submitting &&
             this.renderMessage('验证码错误')}
             <Mobile name="mobile" />
             <Captcha name="captcha" />
         </Tab>
         <div>
             <Checkbox checked={autoLogin} onChange={this.changeAutoLogin}>
             自动登录
             </Checkbox>
             <a style={{ float: 'right' }} href="">
             忘记密码
             </a>
         </div>
         <Submit loading={submitting}>登录</Submit>
         <div className={styles.other}>
             其他登录方式
             <Icon className={styles.icon} type="alipay-circle" />
             <Icon className={styles.icon} type="taobao-circle" />
             <Icon className={styles.icon} type="weibo-circle" />
             <Link className={styles.register} to="/user/register">
             注册账户
             </Link>
         </div>
         </Login>
     </div>
     );
 }
 }

登录处理

文件路径:app/src/model/login.js

import { routerRedux } from 'dva/router';
 import { stringify } from 'qs';
 import { fakeAccountLogin } from '../services/api';
 import { setAuthority } from '../utils/authority';
 import { reloadAuthorized } from '../utils/Authorized';
 import { getPageQuery } from '../utils/utils';
 
 export default {
 namespace: 'login',
 
 state: {
     status: undefined,
 },
 
 effects: {
     *login({ payload }, { call, put }) {
     const response = yield call(fakeAccountLogin, payload);
     yield put({
         type: 'changeLoginStatus',
         payload: response,
     });
     // Login successfully
     if (response.status === 'ok') {
         reloadAuthorized();
         const urlParams = new URL(window.location.href);
         const params = getPageQuery();
         let { redirect } = params;
         if (redirect) {
         const redirectUrlParams = new URL(redirect);
         if (redirectUrlParams.origin === urlParams.origin) {
             redirect = redirect.substr(urlParams.origin.length);
             if (redirect.startsWith('/#')) {
             redirect = redirect.substr(2);
             }
         } else {
             window.location.href = redirect;
             return;
         }
         }
         yield put(routerRedux.replace(redirect || '/'));
     }
     },
     *logout(_, { put }) {
     yield put({
         type: 'changeLoginStatus',
         payload: {
         status: false,
         currentAuthority: 'guest',
         },
     });
     reloadAuthorized();
     yield put(
         routerRedux.push({
         pathname: '/user/login',
         search: stringify({
             redirect: window.location.href,
         }),
         })
     );
     },
 },
 
 reducers: {
     changeLoginStatus(state, { payload }) {
     setAuthority(payload.currentAuthority);
     return {
         ...state,
         status: payload.status,
         type: payload.type,
     };
     },
 },
 };

调用rest接口

文件目录:app/src/services/api.js

// 方法名:fakeAccountLogin
 export async function fakeAccountLogin(params) {
 return request('/api/login/account', {
     method: 'POST',
     body: params,
 });
 }

登录默认路径

ant登录主要是看有没有上次登录地址,如果没有则重定向根目录/,也就是会定向到路由数组的第一个值
在登录完成处理中的定义返回的首次登录路由,更改如下:

// Login successfully
   if (response.status === 'ok') {
     reloadAuthorized();
     const urlParams = new URL(window.location.href);
     const params = getPageQuery();
     // gxg 如果是用户登录时返回登录路径,则以用户登录路径为准
     let defaultPath = response.path;
     if(defaultPath){
       yield put(
         routerRedux.push({
           pathname: defaultPath,
           search: stringify({
             redirect: window.location.href,
           }),
         })
       );
     }else{
       let { redirect } = params;
       if (redirect) {
         const redirectUrlParams = new URL(redirect);
         if (redirectUrlParams.origin === urlParams.origin) {
           redirect = redirect.substr(urlParams.origin.length);
           if (redirect.startsWith('/#')) {
             redirect = redirect.substr(2);
           }
         } else {
           window.location.href = redirect;
           return;
         }
       }
       // 重定向路径
       yield put(routerRedux.replace(redirect || '/'));
     }
 
   }

.roadhogrc.mock.js模拟rest api要进行更改

'POST /api/login/account': (req, res) => {
const { password, userName, type } = req.body;
if (password === '888888' && userName === 'admin') {
  res.send({
    status: 'ok',
    type,
    currentAuthority: 'admin',
    path: '/profile/basic',
  });
  return;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gosenkle/article/details/81627611

相关文章

网友评论

      本文标题:react之Ant Design Pro系列快速入门(二)--登

      本文链接:https://www.haomeiwen.com/subject/hgcupctx.html