极客react之Ant Design Pro系列快速入门(二)--登录与默认路径篇
程序员文章站
2024-02-13 16:56:10
...
登录
-
在启动篇中加载全局路由时有一句代码如下,方法返回路径和对应的界面
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/info': { name: '分步表单(填写转账信息)', component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step1')), }, '/form/step-form/confirm': { name: '分步表单(确认转账信息)', component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step2')), }, '/form/step-form/result': { name: '分步表单(完成)', component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step3')), }, '/form/advanced-form': { component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/AdvancedForm')), }, '/list/table-list': { component: dynamicWrapper(app, ['rule'], () => import('../routes/List/TableList')), }, '/list/basic-list': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/BasicList')), }, '/list/card-list': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/CardList')), }, '/list/search': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/List')), }, '/list/search/projects': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/Projects')), }, '/list/search/applications': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/Applications')), }, '/list/search/articles': { component: dynamicWrapper(app, ['list'], () => import('../routes/List/Articles')), }, '/profile/basic': { component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/BasicProfile')), }, '/profile/advanced': { component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/AdvancedProfile') ), }, '/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; }
上一篇: 简单了解 React中的路由模式
下一篇: react中的路由----基本使用