路由模块(Router)

优质
小牛编辑
134浏览
2023-12-01

概述:

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

 

如上图,我们可以看到在URL中#!后面的部分是随着页面中组件contents的切换而变化的,这就是前端路由的能力-有状态的URL(URL中会反映出当前页面内的需要关心的状态),同样的如果你手动把URL中的#!content-1 改成#!content-2 你会发现contents是会切换到第二个页面,同时不会有后台请求发送的哦。

这里要注意下:我们可以发现虽然URL变化了,但是并没有发送后端请求,这就是所谓的前端路由,一般情况是随着URL变化,普通的后端路由情况是会重新发送请求获取页面的.

同时如果把这个有状态的URL分享出去,打开这个URL后这个页面同样能定位到相应状态,如下图

contents

这个时候,机智的朋友就会说了,既然手动修改URL能切换到第二个页面,那么我写一个<a href=”#!content-2″/>是不是也能切换到第二个页面?答案是当然,同学你果然机智!这就是我们前端路由模块要支持的能力-支持hashbang写法的链接。

好了,说了这么多估计大家已经明白前端路由大致是个什么东东了把。其实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来完成异步处理。