有没有发现,在大家应用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局部,pathnamequery,有很多第三方库提供解析它们的办法,比方:

  • 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 />}    </>  );};

发动路由跳转

基于pushStatereplaceState,封装一下就能够了:

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,弹窗翻身记...】