专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
前端早读课  ·  【招聘】抖音搜索招前端研发工程师/高级前端研 ... ·  22 小时前  
前端早读课  ·  【第3457期】揭秘!如何将动效描述自动转化 ... ·  22 小时前  
前端大全  ·  尤雨溪推荐的全新Vue动画库!真酷 ·  昨天  
前端大全  ·  126K + 30K ... ·  昨天  
51好读  ›  专栏  ›  前端大全

React 如何优雅地写单页面应用?

前端大全  · 公众号  · 前端  · 2017-06-26 19:58

正文

本文作者:张小龙,美团前端工程师,来自作者的知乎专栏


为了追求极致的用户体验,很多Web应用采用单页面方式呈现,然而单页面应用,往往对应着高复杂度,比如多层次路由配置、统一数据处理等,这需要项目有一个强大的技术架构和友好的构建环境来支撑。路由器,作为单页面构建的基础,对单页面应用的开发、加载、运行各个环节都起着至关重要的作用,项目体量越大,对路由器的依赖表现越强。



下面是一个React应用的基础路由配置,了解React的同学一定不陌生:


const App = () => {

return (

< HashRouter >

< div >

< Route cache component = { Home } path = "/" />

< Route component = { Products } path = "/products" />

div >

HashRouter >

)

}

ReactDOM . render ( < App /> , document . getElementById ( 'root' ))


是啊,路由配置不就这么简单吗?


真正做过单页面应用的同学要反驳你了,并且会立刻提出很多问题:

  1. 路由配置拆分怎么做?

  2. 动态加载怎么做?

  3. props怎么传递?

  4. 登录拦截怎么做?

  5. 列表页能不能缓存?

  6. balabala......

能遇到这些问题的同学,相信一定是饱经风霜了。这些问题,Demo中是不会有的,都是真实项目中才能遇到的。


当然,这篇文章,就是为解决这些问题而生的,下面我们以React-Keeper(以下简称Keeper)为例,来解决这些问题。


BTW: React-Keeper是React生态里一款较新的开源路由库,由国内团队开发,借鉴了React-Router 4很多特点,不过灵活性、实用性都强于React-Router很多,而且兼容React-Router常用用法,其文档和代码可以参见React-Keeper GitHub官网。



1. 路由拆分


集中化的路由配置是一个很糟糕的方案,尤其是在大型Web应用中,路由拆分是很有必要的。


Keeper实现路由拆分的方式:


const App = () => {

return (

< HashRouter >

< div >

< Route cache component = { Home } path = "/" />

< Route component = { Products } path = "/products" />

div >

HashRouter >

)

}

const Products = () => {

return (

< div >

< Route component = { ScienceProducts } path = "/sci" />

< Route component = { DailiUseProducts } path = "/dai" />

div >

)

}

ReactDOM . render ( < App /> , document . getElementById ( 'root' ))



实际开发中可以将大量的路由配置信息,按照模块化的方式进行拆分,跟路由只引入模块入口,内部页面配置在模块内部,模块内可以再切分二级模块,以此实现路由的拆分。


2. 动态加载


把所有的JS文件打包为一个文件并不是一个明智的选择,这样会严重拖慢首屏的加载时间,JS代码应该是分割的,并且是按需加载的。


Keeper实现按需加载的方式:


// 定义动态加载函数

const loadProduct = ( cb ) => {

System . import ( '../Products.js' ). then (( Products ) => {

cb ( Products )

})

}

// 通过loadComponent属性引入

< Route loadComponent = { loadProduct } path = '/products' />


3. props传递


我们知道在React-Router中并不支持自定义props的传递,然而这在Keeper中支持得很好:


let hostUser = { id : 'ASDFSDFG' , name : '马化腾' }

// 父组件中通过props传入Route (hostUser)

const Products = () => {

return (

< div >

< Route hostUser = { hostUser } component = { ScienceProducts } path = "/sci" />

< Route component = { DailiUseProducts } path = "/dai" />

div >

)

}

// Route组件所有的props自动传入子组件

const ScienceProducts = ( props ) => {

return (

< div >

< h3 > { props . hostUser . name } h3 >

div >

)

}


4. 登录拦截


登录拦截、权限检测、表单关闭检测,这些是业务中非常常见的场景,而这也在Keeper中得到了很好的支持。


Keeper提供了两种过滤器来对路由的状态变化进行过滤和拦截:EnterFilter和LeaveFilter。

EnterFilter: 进入页面之前执行的过滤器,适用于登录检测、权限检测一类的场景。


LeaveFilter: 页面解绑之前执行的过滤器,适用于表单关闭检测一类的场景。


// 定义过滤器,内部通过callback进行流程控制

const loginFilter = ( callback , props ) => {

if ( ! props . host ) {

new Promise (( resolve , reject ) => {

// some code

}). then ( callback );

}

}

// 将过滤器加入Route

<







请到「今天看啥」查看全文