1. 从数据流开始,分析 antd
最直接的办法就是看代码了,首先分析一下登录过程的数据流向,登录界面对应的 js 文件在 src/pages/User/Login.js,
自动忽略所有代码是啥意思,找到下面的代码:
// 登录提交 handleSubmit = (err, values) => { const { type } = this.state; const { dispatch } = this.props; if (!err) { dispatch({ // dispath 用于派发请求,调用的 model 的 effects type: 'login/login', //调用统一管理的 service 请求函数: 模块命名空间为login/下的 login effects请求 payload: { //payload: 传递过去的参数 ...values, type, }, }); } };
嗯,重点看到 login/login , 这是 react-router 组件跳转的方式,payload 是参数,这里的 login/login 跳转到哪里?前边的 login 代表着 model,也就是 src/models 目录下的文件。具体是怎么关联的呢?
说明:在 src/.umi (该目录是 umi 自动生成的) 目录下的 initDva.js 文件中具有 model 设置:
app.model({ namespace: 'login', ...(require('.../ant-design-pro2.0/src/models/login.js').default) }); //'login', 就表示 src/models 目录下对应的那个 js 文件(文件中的 namespace='login') 或者 pages/自己目录下/models 目录下对应的 js 文件
找到 src/models/login.js 文件,找到:
*login({ payload }, { call, put }) { // 此处的 payload 对应上面 handleSubmit 中 dispath() 传过来的参数 payload // 请求后台数据接口 const response = yield call(fakeAccountLogin, payload); // yield call(调用后台接口的方法,传过去的参数):来调用(数据接口方法 和 请求参数),yield表示同步调用,这个是generator提供的功能 // 存储后端接口返回的数据 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.match(/^\/.*#/)) { redirect = redirect.substr(redirect.indexOf('#') + 1); } } else { window.location.href = redirect; return; } } yield put(routerRedux.replace(redirect || '/')); } },
这样的话,组件间数据的流向就跟清楚了,要想明白具体是怎么实现的请先学习 react, react-router, redux
学完这些,上边的流程自然就能明白是啥意思了。
剩下的就是怎么获取后台数据了,
const response = yield call(fakeAccountLogin, payload); // 使用call(function,param)获取后台数据,后台返回结果存储在 response 里,fakeAccountLogin 是方法,定义在 services 文件夹下的某个文件里, 该版本在 @/services/api.js 文件中
找到方法的位置,此版本在 services/api.js 文件里,找到方法:
export async function fakeAccountLogin(params) { return request('/api/login/account', { // 发送后台请求:具体的后台接口,此处接口是 mock 模拟的,查找后 mock/user.js/ "POST /api/login/account" method: 'POST', body: params, }); }
接着,使用 yield put 存储返回数据:
// 调用后台数据接口 const response = yield call(fakeAccountLogin, payload); // 调用后端数据服务 fakeAccountLogin // 获取服务端返回,存储数据 yield put({ type: 'changeLoginStatus', // reducer处理:调用该文件自己的方法 payload: response, });
其中, reducer 处理方法 changeLoginStatus,在 models 下的 reducer 处理处,此处在 src/models/login.js 文件。
reducers: { changeLoginStatus(state, { payload }) { setAuthority(payload.currentAuthority); // 本地登录权限认证 return { // 本地 state 数据状态更新 ...state, status: payload.status, type: payload.type, }; }, }, 其中, setAuthority 设置权限认证,utils/authority.js/ function
export function setAuthority(authority) { const proAuthority = typeof authority === 'string' ? [authority] : authority; return localStorage.setItem('antd-pro-authority', JSON.stringify(proAuthority)); }
接着,登录成功处理:
// 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.match(/^\/.*#/)) { redirect = redirect.substr(redirect.indexOf('#') + 1); } } else { redirect = null; } } yield put(routerRedux.replace(redirect || '/')); // 路由跳转 } 其中,reloadAuthorized() , 更新认证, utils/Authorizedd.js/ const func // Reload the rights component const reloadAuthorized = () => { Authorized = RenderAuthorize(getAuthority()); };
至此,登录结束。
ant design pro 采用 dva 框架 进行管理,所有你要找到 后台接口,该版本在 mock/user.js 文件中 ,看到
POST /api/login/account': (req, res) => { //...... }
在这里获取后台数据。以上就是完整的数据交互的流程 ,下面是学习三周后做的一个例子:
2、demo
主要的功能:用ant design 提供的组件完成对数据库的曾删改查的操作:
参考:https://blog.csdn.net/u013416951/article/details/81133733