![c893fa0191e94fe680591d0d073ce461.png](https://i-blog.csdnimg.cn/blog_migrate/f29868ba002ec0b3c194aca3e7db443a.jpeg)
权限路由
根据服务端返回的权限key,来判断本地路由是否有访问权限,然后根据权限渲染页面。
const App=()=>{
const [permission,setPermission]=useState(null);
useEffect(()=>{
const getPerm=async ()=>{
try{
const {permList}=await getPermission({time:+new Date()});
setPermission(permList||[]);
}catch(err){
setPermission([]);
}
};
getPerm();
},[]);
if(!permission){
// return <Skeleton />;
return <Spinner global />;
}
return <ConfigProvider permission={[...permission,...whiteRouters]} />;
};
路由白名单,不需要权限控制的。如登录注册页面、404页面。
export const whiteRouters=[
'/user',
'/user/signin',
'/user/signup',
'/404',
];
i18n
将语言信息(zh、en...)存入storage,然后根据language获取系统语言库,将语言库存入store,以供页面使用。
const ConfigProvider=({permission})=>{
const language=storage.get('language')||'zh';
const {router,title}=i18ns[language];
const {output,loading,store,updateRouter}=useRouter({...configs,routers:permRouter(routers(router),permission),title});
useEffect(()=>{
const {subscribe,setState}=store;
setState({permission});
setState({langCfg:{...i18ns[language],language}});
subscribe('update-router',result=>{
updateRouter({routers:result.menu,exact:true});
});
subscribe('change-language',language=>{
storage.set('language',language);
const {router,title}=i18ns[language];
setState({langCfg:{...i18ns[language],language}});
updateRouter({routers:permRouter(routers(router),permission),title});
});
},[]);
return <>
{output}
{loading&&<Spinner global />}
</>;
};
i18n
import zh from './zh';
import en from './en';
import jp from './jp';
export default {
zh,
en,
jp,
};
语言信息可以根据页面来制定,如首页语言包:
home.js
const home={
title:'首页',
};
切换语言
通过订阅发布模式,触发语言信息变更,然后获取新的语言包,重新渲染页面。
subscribe('change-language',language=>{
storage.set('language',language);
const {router,title}=i18ns[language];
setState({langCfg:{...i18ns[language],language}});
updateRouter({routers:permRouter(routers(router),permission),title});
});
路由过渡效果
可根据设计自定义各种路由切换动画效果。路由切换时,平台的layout大致保持不变,主要是view页面的变更,我们可以监听路由变化,在container上加减样式,以实现路由过渡效果。
const time=350;
const Index=props=>{
const {menu,current,children,inputPath,collapsed,handleCollapse,store}=props;
const langCfg=store?.getState('langCfg')??{};
const {main:{bread}}=langCfg;
const hasMenu=menu?.length;
const style=hasMenu?null:{paddingLeft:0};
const viewRef=useRef();
const pathRef=useRef(inputPath);
const timer=useRef();
useEffect(()=>{
if(inputPath!==pathRef.current){
pathRef.current=inputPath;
addClass(viewRef.current,'ani-in');
timer.current=setTimeout(()=>{
removeClass(viewRef.current,'ani-in');
},time);
}
return ()=>clearTimeout(timer.current);
},[inputPath]);
return <div className="frame-container">
{
hasMenu?<aside className="frame-aside">
<Menu key={inputPath} menu={menu} curPath={current.slice(-1)[0]?.path} collapsed={collapsed} handleCollapse={handleCollapse} />
</aside>:null
}
<div className="frame-view" style={style}>
<div className="page-container">
{breadcrumb(current||[],bread)}
<div className="content" ref={viewRef}>
{children}
</div>
</div>
</div>
</div>;
};