有没有发现,在大家使用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.eluxjs.com/

该项目中,没有使用任何第三方Router框架,全凭自己撸,那感觉也挺好的...

手撸Router,还要啥Router框架?react-router/vue-router躺一边去的更多相关文章

  1. 手撸基于swoole 的分布式框架 实现分布式调用(20)讲

    最近看的一个swoole的课程,前段时间被邀请的参与的这个课程 比较有特点跟一定的深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. 内容听 ...

  2. 手撸ORM浅谈ORM框架之基础篇

    好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...

  3. 手撸ORM浅谈ORM框架之Add篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  4. 手撸ORM浅谈ORM框架之Update篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  5. 手撸ORM浅谈ORM框架之Delete篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  6. 手撸ORM浅谈ORM框架之Query篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  7. 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...

  8. 【RPC】手撸一个简单的RPC框架实现

      涉及技术   序列化.Socket通信.Java动态代理技术,反射机制   角色   1.服务提供者:运行在服务端,是真实的服务实现类   2.服务发布监听者:运行在RPC服务端,1将服务端提供的 ...

  9. C#基于Mongo的官方驱动手撸一个Super简易版MongoDB-ORM框架

    C#基于Mongo的官方驱动手撸一个简易版MongoDB-ORM框架 如题,在GitHub上找了一圈想找一个MongoDB的的ORM框架,未偿所愿,就去翻了翻官网(https://docs.mongo ...

  10. Vue技术点整理-Vue Router

    路由 Vue Router 对于单页面应用来说,如果涉及到多个页面的话,就必须要使用到路由,一般使用官方支持的 vue-router 库 一,Vue Router 在项目中的安装引用 1,在页面中使用 ...

随机推荐

  1. Vscode个性化设置:让一个小萌妹陪你敲代码

    前言 大家平时都用什么代码编辑器啊!我个人比较喜欢用vscode,因为有以下几点: 开源,免费: 自定义配置 集成git 智能提示强大 支持各种文件格式(html/jade/css/less/sass ...

  2. vue大型电商项目尚品汇(后台终结篇)day06 重磅!!!

    自此整个项目前后台,全部搭建完毕. 今天是最后一天,内容很多,而且也比较常用,一个图标类数据可视化,一个后台的权限管理,都是很经典的类型. 一.数据可视化 1.简介 专门的一门学科,有专门研究这个的岗 ...

  3. UiPath屏幕抓取Screen Scraping的介绍和使用

    一.屏幕抓取(Screen Scraping)的介绍 屏幕抓取使您能够在特定的UI元素或文档(如.PDF文档)中提取数据 二.屏幕抓取(Screen Scraping)在UiPath中的使用 [if ...

  4. sql-DCL用户及权限管理及其他常用命令-oracle

    DCL 用户管理 创建用户 create user 用户名 identified by 密码; 在oracle中要创建一个新的用户使用create user语句,一般是具有dba(数据库管理员)的权限 ...

  5. 一张图进阶 RocketMQ - 消息发送

    前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦. [重要]视频在 B 站同步更新,欢 ...

  6. Tomcat深入浅出——Filter与Listener(五)

    一.Filter过滤器 1.1 Filter过滤器的使用 这是过滤器接口的方法 public interface Filter { default void init(FilterConfig fil ...

  7. JavaWEB04-Maven&Mybatis

    今日内容 `Maven` Maven `Maven`概念&简介 Maven `Maven`安装配置 Maven `Maven`基本使用 Idea集成 `Idea`集成`Maven` Maven ...

  8. Java方法的重写

    package Demo.oop.APP.Demo04; //启动器 public class application { public static void main(String[] args) ...

  9. java的方法(类似与C语言函数)

    package www.nihao; import java.util.Scanner; public class demo02 { public static void main(String[] ...

  10. C++几种特殊形式的函数

    本篇文章主要介绍C++语言中5中特殊形式的函数,分别是带默认形参值的函数.重载函数.内联函数.带形参和返回值的主函数以及递归函数. 一.带默认形参值的函数 如果函数的形参在多数情况下都可以取某个固定的 ...