有没有发现,在大家应用React/Vue的时候,总离不开一个小尾巴,到哪都得带着他,那就是react-router/vue-router,而基于它们的第三方框架又呈现很多个性化约定和扩大,比方nuxtjs/nextjs/umijs都纷纷推出本人的路由计划。
有没有想过,其实你能够齐全解脱他们都解放?而且并不简单,上面听我来剖析剖析:
State能够管制所有UI
首先React/Vue都是基于MVVM架构,State能够决定Component的显示与否,而且很简略:
// jsx{show? <SubUI /> : null}// vue<SubUI v-if="show" />
也能够依据State来动态显示组件:
<component :is="componentA"></component>
管制UI的办法有很多,我就不例举了,总之State才是掌控UI的大脑中枢。
将URL映射为State
路由的作用,无非就是依据Url来管制UI展现,那么你只须要将Url映射成为State,不就达到目标了?
Url次要分2局部,pathname
和query
,有很多第三方库提供解析它们的办法,比方:
pathname解析:path-to-regexp:
const regexp = pathToRegexp("/:foo/:bar");regexp.exec("/test/route");
具体用法大家看看官网文档就能够了,很简略...
query解析:query其实很灵便,没有规定非得用什么格局,最简略的你间接用JSON.stringify将序列化后的字符串作为query也能够,如果你想遵循罕用的格局,你能够应用:query-string 或者 qs
queryString.parse(location.search)
好了,当初你能够拿到解析Url后的数据,而后把它们转换成你想要的State,寄存在全局Store中就能够了,比方你定义一个Url:
/member/list/3?uname=lily
//提取路由信息getRouteParams(): RouteParams { const query = queryString.parse(location.search); const [, curModule='', curView='', id=''] = pathToRegexp('/:curModule/:curView/:id') .exec(location.pathname) || []; if (curView === 'list') { //如果是列表,ID示意以后页码 return {...query, pageCurrent: id, curView} } else if(curView === 'detail') { return {...query, id, curView} }}
而后在UI中拿到这几个State(可通过Redux或Vuex):
const Component = ({curView}) => { return ( <> {curView === 'list' && <List />} {curView === 'detail' && <Detail />} </> );};
发动路由跳转
基于pushState
和replaceState
,封装一下就能够了:
window.history.pushState(null, '', url);window.history.replaceState(null, '', url);
const Link = ({url, action, ...props}) => { const onClick = (event: MouseEvent) => { event.preventDefault(); window.history[`${action}State`](null, '', url); } return <a onClick={onClick} {...props} />;}
监听路由变动
监听popstate
事件就行了:
window.addEventListener('popstate',() => { //解析Url并更新Store //...});
手撸的益处
- UI渲染更纯正,将UI的生杀大权牢牢把握在State手中,
UI = render(state)
,路由和其它因子都被挡在外围,当作一种影响State的副作用之一。
- 灵活性更高,你能够把URL映射成为任何State,从而管制任何State能管制的货色,比方用Url来管制一个按钮的启用与禁用,弹窗的弹出与敞开等等。
- 不依赖各种第三方框架,不必学习它们,也不受它们的束缚。
- UI和Router之间没有间接绑定,而是通过State映射,这意味着如果产品优化、路由格局变动,改变的只是映射,而不必动到View和State,这样更涣散。
理论案例
以上所说只是一个大体思路,真正要用得不便,还得做一些细节的封装和改变,这里提供一个本人的开源我的项目供大家参考,在线预览:http://admin-react-antd.eluxj...
该我的项目中,没有应用任何第三方Router框架,全凭本人撸,那感觉也挺好的...
React版本
- github: https://github.com/hiisea/elu...
- gitee: https://gitee.com/hiisea/elux...
Vue版本
- github: https://github.com/hiisea/elu...
- gitee: https://gitee.com/hiisea/elux...
另外将这种手撸机制,天马行空的与Dialog联合,就诞生出一个神器:虚构Window
,能够查看我的另一篇文章:【不想当Window的Dialog不是一个好Modal,弹窗翻身记...】