在对vue框架学习的比较熟练之后,我开始尝试尝试使用react框架来实现一些新的项目。这篇文章主要是断更这些天里,从最近写的项目里的总结,实现的是基于react umi 搭建的管理系统。
登录系统
凡是一个完整的系统一定具有的功能就是登录了。目前大多数网站都是区分用户权限的,最常见的就是视频网站里面的VIP用户和普通用户,某些特定的网页也只有对应身份的用户才开放。登录系统最基础的功能就是可以把用户划分成不同类型。
在用户访问我的网页时,首先会出现的是登录页面。用户在登录时提供了两种登录方式账号密码登录和手机验证码登录。
在用户登录成功之后,就会接收到后端返回的token字段,采用sessionStorage将字段保存到本地并设置一个全局变量来保存用户的信息。
首先基于umi的fetch封装一个HTTP类来完成后端接口请求操作
class HTTP {
static async staticFetch(url = '', options = {}) {
url = "/api" + url;
// 声明默认的配置信息
const defaultOptions = {
mode: "cors",
headers: {
token: sessionStorage.getItem('token') || null,
},
}
if (options.method === "POST" || options.method === "PUT") {
defaultOptions.headers['Content-type'] = "application/json;charset=utf-8";
}
const newOptions = { ...defaultOptions, ...options };
// 可以封装一些方法来完善不同的请求情况
return fetch(url, newOptions).then(res => {
const token = res.headers.get('token');
token && sessionStorage.setItem('token', token);
return res.json()
}).catch(handlerError)
}
get(url, option = {}) {
const options = Object.assign({ method: 'GET' }, option);
Object.keys(options) && (url += '?' + qs.stringify(option))
return HTTP.staticFetch(url, options)
}
post(url, params = {}, option = {}) {
const options = Object.assign({ method: 'POST' }, option);
options.body = JSON.stringify(params);
return HTTP.staticFetch(url, options)
}
}
开启一个全局的 model 储存用户信息
{
namespace: 'user',
state: {
userInfo: sessionStorage.getItem('userProfile') ? JSON.parse(sessionStorage.getItem('userProfile')) : null
},
reducers: {
updateUserProfile: (state, {payload}) => ({
...state,
...payload
})
},
effects: {
*login({ payload }, { put, call, select }) {
const { data, mes } = yield call($http.userLogin, payload);
if (!data) {
message.error(mes)
return
}
sessionStorage.setItem('userProfile', data);
yield put({
type: 'updateUserProfile',
payload: {userInfo: data}
})
}
}
}
路由守卫
在平时我们逛淘宝的时候,当你点击了购买按钮的时候,你会发现弹出的不是订单界面而是切换到了登录页面。没有用户信息就无法涉及到商品系列的操作,这种情况是非常符合逻辑的。这时候所涉及到的就是路由守卫,他的原理就是网页的路由跳转拦截。
在umi框架中是基于sunscriptions事件派发实现。在全局model里处理
{
namespace: 'common',
state: {
},
subscriptions: {
setup({dispatch, history}){
// 初始化查询用户是否登录, app.start阶段进行执行
dispatch({type: 'queryUserLogin', payload: {history}})
},
},
effects: {
*queryUserLogin({payload}, {put, call}){
// 判断用户当前访问的路径
const {history, history: {location: {pathname}}} = payload;
if(pathname !== '/users/login'){
// 处理登录信息
if(!sessionStorage.getItem('userProfile') || !sessionStorage.getItem('token') || !sessionStorage.getItem('routeList')){
history.replace('/users/login');
}else{
// 用户满足条件还需进行信息验证
const res = yield call($http.queryUserLogin);
if (res.code !== 0) {
return;
}
// 路由表由接口获取
const {data: routeList} = yield call($http.getRouteList);
sessionStorage.setItem('routeList', JSON.stringify(routeList));
}
}else{
// 非拦截页面
sessionStorage.clear();
}
}
}
}