手撸Router,还要啥Router框架?react-router/vue-router躺一边去
有没有发现,在大家使用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.eluxjs.com/
该项目中,没有使用任何第三方Router框架,全凭自己撸,那感觉也挺好的...
- React版本
- Vue版本
手撸Router,还要啥Router框架?react-router/vue-router躺一边去的更多相关文章
- 手撸基于swoole 的分布式框架 实现分布式调用(20)讲
最近看的一个swoole的课程,前段时间被邀请的参与的这个课程 比较有特点跟一定的深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. 内容听 ...
- 手撸ORM浅谈ORM框架之基础篇
好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...
- 手撸ORM浅谈ORM框架之Add篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Update篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Delete篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Query篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...
- 【RPC】手撸一个简单的RPC框架实现
涉及技术 序列化.Socket通信.Java动态代理技术,反射机制 角色 1.服务提供者:运行在服务端,是真实的服务实现类 2.服务发布监听者:运行在RPC服务端,1将服务端提供的 ...
- C#基于Mongo的官方驱动手撸一个Super简易版MongoDB-ORM框架
C#基于Mongo的官方驱动手撸一个简易版MongoDB-ORM框架 如题,在GitHub上找了一圈想找一个MongoDB的的ORM框架,未偿所愿,就去翻了翻官网(https://docs.mongo ...
- Vue技术点整理-Vue Router
路由 Vue Router 对于单页面应用来说,如果涉及到多个页面的话,就必须要使用到路由,一般使用官方支持的 vue-router 库 一,Vue Router 在项目中的安装引用 1,在页面中使用 ...
随机推荐
- Vscode个性化设置:让一个小萌妹陪你敲代码
前言 大家平时都用什么代码编辑器啊!我个人比较喜欢用vscode,因为有以下几点: 开源,免费: 自定义配置 集成git 智能提示强大 支持各种文件格式(html/jade/css/less/sass ...
- vue大型电商项目尚品汇(后台终结篇)day06 重磅!!!
自此整个项目前后台,全部搭建完毕. 今天是最后一天,内容很多,而且也比较常用,一个图标类数据可视化,一个后台的权限管理,都是很经典的类型. 一.数据可视化 1.简介 专门的一门学科,有专门研究这个的岗 ...
- UiPath屏幕抓取Screen Scraping的介绍和使用
一.屏幕抓取(Screen Scraping)的介绍 屏幕抓取使您能够在特定的UI元素或文档(如.PDF文档)中提取数据 二.屏幕抓取(Screen Scraping)在UiPath中的使用 [if ...
- sql-DCL用户及权限管理及其他常用命令-oracle
DCL 用户管理 创建用户 create user 用户名 identified by 密码; 在oracle中要创建一个新的用户使用create user语句,一般是具有dba(数据库管理员)的权限 ...
- 一张图进阶 RocketMQ - 消息发送
前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦. [重要]视频在 B 站同步更新,欢 ...
- Tomcat深入浅出——Filter与Listener(五)
一.Filter过滤器 1.1 Filter过滤器的使用 这是过滤器接口的方法 public interface Filter { default void init(FilterConfig fil ...
- JavaWEB04-Maven&Mybatis
今日内容 `Maven` Maven `Maven`概念&简介 Maven `Maven`安装配置 Maven `Maven`基本使用 Idea集成 `Idea`集成`Maven` Maven ...
- Java方法的重写
package Demo.oop.APP.Demo04; //启动器 public class application { public static void main(String[] args) ...
- java的方法(类似与C语言函数)
package www.nihao; import java.util.Scanner; public class demo02 { public static void main(String[] ...
- C++几种特殊形式的函数
本篇文章主要介绍C++语言中5中特殊形式的函数,分别是带默认形参值的函数.重载函数.内联函数.带形参和返回值的主函数以及递归函数. 一.带默认形参值的函数 如果函数的形参在多数情况下都可以取某个固定的 ...