ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 路由模块(Router) # 概述: Router是一种根据不同URL的来表现的页面状态的能力,基于HTML5 history api实现. Router模块提供了根据不同组件state、model的states、以及自定义states来实现的对浏览器的前进后退导航、有状态的书签、可分享的URL、URL自定义处理器等支持。如果你曾经使用过一些后端框架比如Express、Sinatra、Play,那么你将会发现和他们的想法非常相似。 # 为什么要基于客户端的URL路由: URL是维护一个web app的状态的非常好的方法,因为URL很容易被看到,很容易修改,而且可以被存储为书签和分享。 原本我们在服务端的web框架中使用URL路由技术,来达到根据不同的URL,不同的参数来返回不同的页面, 现在我们可以配合客户端的URL路由技术来达到更好用户体验。 # 客户端路由能做什么: [![contents](https://box.kancloud.cn/2015-09-24_5602ec8f82a90.gif)](https://box.kancloud.cn/2015-09-24_5602ec8f82a90.gif) 如上图,我们可以看到在URL中#!后面的部分是随着页面中组件contents的切换而变化的,这就是前端路由的能力-有状态的URL(URL中会反映出当前页面内的需要关心的状态),同样的如果你手动把URL中的#!content-1 改成#!content-2 你会发现contents是会切换到第二个页面,同时不会有后台请求发送的哦。 这里要注意下:我们可以发现虽然URL变化了,但是并没有发送后端请求,这就是所谓的前端路由,一般情况是随着URL变化,普通的后端路由情况是会重新发送请求获取页面的. 同时如果把这个有状态的URL分享出去,打开这个URL后这个页面同样能定位到相应状态,如下图 [![contents](https://box.kancloud.cn/2015-09-24_5602ec90a7dbc.gif)](https://box.kancloud.cn/2015-09-24_5602ec90a7dbc.gif) 这个时候,机智的朋友就会说了,既然手动修改URL能切换到第二个页面,那么我写一个是不是也能切换到第二个页面?答案是当然,同学你果然机智!这就是我们前端路由模块要支持的能力-支持[hashbang](https://developers.google.com/webmasters/ajax-crawling/docs/getting-started?csw=1)写法的链接。 好了,说了这么多估计大家已经明白前端路由大致是个什么东东了把。其实Router模块的实现并不是只有上面例子看起来那么简单。 # Router模块有什么: ### 首先我们看下Router对应的代码主要的的模块文件 * hashbangParser.js * router.js * routeState.js * 如果说组件就是一个状态机,根据不同的状态响应不同的逻辑、展现,那么每个组件可以把自己的状态反映到URL中,但是WeX5的页面是有很多model(可以认为一个.w页面就是一个model) 组合出来的,所以我们认为每个model需要维护当前model下状态的,所有每个model下就有一个对象$routeState. * model的状态变化了,他有可能是根model(比如在portal中的portal页面),他有可能是子model(比如portal中打开的页面,windowDialog打开的页面等),那么这些状态怎么合并,怎么向上传递,父model收到变化通知要向子model分发,等问题,所以就有了router.js * 上面说到可能会到复杂的嵌套、组合等情况,那么url毕竟要有一定的复杂度,所以我们需要一个parser用来把复杂的url理解成对象。 # Router模块怎么使用: * 现在支持route的组件有contents和dialog(windowDialog).只需要在设计界面设置组件的routable属性为true,组件默认就可以有路由能力。当然组合嵌套情况默认已经支持,不用担心。 * 如果我有自定义路由的需求怎么办? 参考portal中自定义路由相关代码,来看看他是怎么自定义路由的吧。这里就不详细解释代码了。 # Router组件: route组件提供了自定义自己的路由的能力。 api说明: addRouteItem :添加路由项 参数:name, param 从上面介绍已知:路由项有三部分组成 xid\name\param 这里xid为route组件的xid ,name、param就是你可以自定以的。 removeRouteItem:删除路由项 参数:name publishState:把当前路由状态发布出去(最终反映到url上) onRoute : 路由变动事件 (回调形事件) event格式如下 {source":"当前组件", "cancel":"false", "xid":"xid", "name":"name", "param":"param", "routeState":"routeState", "async":"false", "dtd":"dtd" } 你可以通过判断 name来只对你关心的状态变化进行处理 routeState 有三种 enter、leave、update 如果你的处理中有异步逻辑 可以设置async为true 然后通过dtd来完成异步处理。