Dojo 路由
栏目: JavaScript · 发布时间: 6年前
内容简介:Dojo 应用程序的路由部件(Widget)是 Dojo 应用程序的基本概念,因此 Dojo 路由提供了一组与应用程序中的部件直接集成的组件。这些组件能将部件注册到路由上,且不需要掌握路由相关的任何知识。Dojo 应用程序中的路由包括以下内容:
路由
commit b682b06ace25eea86d190e56dd81042565b35ed1
Dojo 应用程序的路由
Features
部件(Widget)是 Dojo 应用程序的基本概念,因此 Dojo 路由提供了一组与应用程序中的部件直接集成的组件。这些组件能将部件注册到路由上,且不需要掌握路由相关的任何知识。Dojo 应用程序中的路由包括以下内容:
-
Outlet部件封装器指定 route 的 outlet key 和表现视图之间的映射关系 -
Route配置,用于在路径和 outlet key 之间建立映射关系 -
Router基于当前路径解析Route -
History提供器负责向Router通知路径的更改 -
Registry将Router注入到部件系统中
Route 配置
RouteConfig
用于注册应用程序的路由,它定义了路由的 path
、关联的 outlet
以及嵌套的子 RouteConfig
。一个完整的路由就是由递归嵌套的 Route 构成的。
路由配置示例:
import { RouteConfig } from '@dojo/framework/routing/interfaces';
const config: RouteConfig[] = [
{
path: 'foo',
outlet: 'root',
children: [
{
path: 'bar',
outlet: 'bar'
},
{
path: 'baz',
outlet: 'baz',
children: [
{
path: 'qux',
outlet: 'qux'
}
]
}
]
}
];
此配置将注册以下路由和 outlet:
| Route | Outlet |
|---|---|
/foo
|
root
|
/foo/bar
|
bar
|
/foo/baz
|
baz
|
/foo/baz/qux
|
qux
|
路径参数
在 RouteConfig
的 path 属性中,在 path
的值中使用大括号可定义路径参数。 Parameters will match any segment and the value of that segment is made available to matching outlets via the Outlet
options. The parameters provided to child outlets will include any parameters from matching parent routes.
const config = [
{
path: 'foo/{foo}',
outlet: 'foo'
}
];
具有路径参数的路由,可为每个路由指定默认的参数。当用没有指定参数的 outlet 生成一个链接,或者当前路由中不存在参数时,可使用这些默认参数值。
const config = [
{
path: 'foo/{foo}',
outlet: 'foo',
defaultParams: {
foo: 'bar'
}
}
];
可使用可选的配属属性 defaultRoute
来设置默认路由,如果当前路由没有匹配到已注册的路由,就使用此路由。
const config = [
{
path: 'foo/{foo}',
outlet: 'foo',
defaultRoute: true
}
];
Router
Router
用于注册,将 route 配置信息传入 Router 的构造函数即可:
const router = new Router(config);
会自动为 router 注册一个 HashHistory
历史管理器(history manager)。可在第二个参数中传入其他历史管理器。
import { MemoryHistory } from '@dojo/framework/routing/MemoryHistory';
const router = new Router(config, { HistoryManager: MemoryHistory });
使用应用程序路由配置创建路由后,需要让应用程序中的所有组件可使用这些路由。这是通过使用 @dojo/framework/widget-core/Registry
中的 Registry
,定义一个将 invalidator
连接到 router 的 nav
事件的注入器,并返回 router
实例实现的。这里使用 key 来定义注入器,路由器的默认 key 值为 router
。
import { Registry } from '@dojo/framework/widget-core/Registry';
import { Injector } from '@dojo/framework/widget-core/Injector';
const registry = new Registry();
// 假设我们有一个可用的 router 实例
registry.defineInjector('router', () => {
router.on('nav', () => invalidator());
return () => router;
};
注意:路由提供了注册 router 的快捷方法。
最后,为了让应用程序中的所有部件都能使用 registry
,需要将其传给 vdom renderer
的 .mount()
方法。
const r = renderer(() => v(App, {}));
r.mount({ registry });
History Managers
路由自带三个历史管理器,用于监视和更改导航状态: HashHistory
、 StateHistory
和 MemoryHistory
。默认使用 HashHistory
,但是可在创建 Router
时传入不同的 HistoryManager
。
const router = new Router(config, { HistoryManager: MemoryHistory });
Hash History
基于哈希的管理器使用片段标识符(fragment identifier)来存储导航状态,是 @dojo/framework/routing
中的默认管理器。
import { Router } from '@dojo/framework/routing/Router';
import { HashHistory } from '@dojo/framework/routing/history/HashHistory';
const router = new Router(config, { HistoryManager: HashHistory });
历史管理器有 current
、 set(path: string)
和 prefix(path: string)
三个API。 HashHistory
类假定全局对象是浏览器的 window
对象,但可以显式提供对象。管理器使用 window.location.hash
和 hashchange
事件的事件监听器。 current
访问器返回当前路径,不带 # 前缀。
State History
基于状态的历史管理器使用浏览器的 history API: pushState()
和 replaceState()
,来添加和修改历史纪录。状态历史管理器需要服务器端支持才能有效工作。
Memory History
MemoryHistory
不依赖任何浏览器 API,而是保持其自身的内部路径状态。不要在生产应用程序中使用它,但在测试路由时却很有用。
import { Router } from '@dojo/framework/routing/Router';
import { MemoryHistory } from '@dojo/framework/routing/history/MemoryHistory';
const router = new Router(config, { HistoryManager: MemoryHistory });
Outlet Event
当每次进入或离开 outlet 时,都会触发 router
实例的 outlet
事件。outlet 上下文、 enter
或 exit
操作都会传给事件处理函数。
router.on('outlet', ({ outlet, action }) => {
if (action === 'enter') {
if (outlet.id === 'my-outlet') {
// do something, perhaps fetch data or set state
}
}
});
Router Context Injection
RouterInjector
模块导出一个帮助函数 registerRouterInjector
,它组合了 Router
实例的实例化,注册 router 配置信息和为提供的 registry 定义注入器,然后返回 router
实例。
import { Registry } from '@dojo/framework/widget-core/Registry';
import { registerRouterInjector } from '@dojo/framework/routing/RoutingInjector';
const registry = new Registry();
const router = registerRouterInjector(config, registry);
可使用 RouterInjectiorOptions
覆盖默认值:
import { Registry } from '@dojo/framework/widget-core/Registry';
import { registerRouterInjector } from '@dojo/framework/routing/RoutingInjector';
import { MemoryHistory } from './history/MemoryHistory';
const registry = new Registry();
const history = new MemoryHistory();
const router = registerRouterInjector(config, registry, { history, key: 'custom-router-key' });
Outlets
路由集成的一个基本概念是 outlet
,它是与注册的应用程序 route 关联的唯一标识符。 Outlet
是一个标准的 dojo 部件,可在应用程序的任何地方使用。 Outlet
部件有一个精简的 API:
-
id: 匹配时执行renderer的 outlet 标识。 -
renderer: 当 outlet 匹配时调用的渲染函数。 -
routerKey(可选): 在 registry 中定义路由时使用的key- 默认为router。
接收渲染的 outlet 名称和一个 renderer
函数,当 outlet 匹配时,该函数返回要渲染的 DNode
。
render() {
return v('div', [
w(Outlet, { id: 'my-outlet', renderer: () => {
return w(MyWidget, {});
}})
])
}
可为 renderer
函数传入 MatchDetails
参数,该参数提供路由专有信息,用于确定要渲染的内容和计算传入部件的属性值。
interface MatchDetails {
/**
* Query params from the matching route for the outlet
*/
queryParams: Params;
/**
* Params from the matching route for the outlet
*/
params: Params;
/**
* Match type of the route for the outlet, either `index`, `partial` or `error`
*/
type: MatchType;
/**
* The router instance
*/
router: RouterInterface;
/**
* Function returns true if the outlet match was an `error` type
*/
isError(): boolean;
/**
* Function returns true if the outlet match was an `index` type
*/
isExact(): boolean;
}
render() {
return v('div', [
w(Outlet, { id: 'my-outlet', renderer: (matchDetails: MatchDetails) => {
if (matchDetails.isError()) {
return w(ErrorWidget, {});
}
if (matchDetails.isExact()) {
return w(IndexWidget, { id: matchDetails.params.id });
}
return w(OtherWidget, { id: matchDetails.params.id });
}})
])
}
Global Error Outlet
只要注册了一个 error
匹配类型,就会自动为匹配的 outlet 添加一个全局 outlet,名为 errorOutlet
。这个 outlet 用于为任何未知的路由渲染一个部件。
render() {
return w(Outlet, {
id: 'errorOutlet',
renderer: (matchDetails: MatchDetails) => {
return w(ErrorWidget, properties);
}
});
}
Link
Link
组件是对 DOM 节点 a
的封装,允许用户为创建的链接指定一个 outlet
。也可以通过将 isOutlet
属性值设置为 false
来使用静态路由。
如果生成的链接需要指定在 route 中不存在的路径或查询参数,可使用 params
属性传入。
import { Link } from '@dojo/framework/routing/Link';
render() {
return v('div', [
w(Link, { to: 'foo', params: { foo: 'bar' }}, [ 'Link Text' ]),
w(Link, { to: '#/static-route', isOutlet: false, [ 'Other Link Text' ])
]);
}
所有标准的 VNodeProperties
都可用于 Link
组件,因为最终是使用 @dojo/framework/widget-core
中的 v()
来创建一个 a
元素。
ActiveLink
ActiveLink
组件是对 Link
组件的封装,如果链接处于激活状态,则可以为 a
节点设置样式类。
import { ActiveLink } from '@dojo/framework/routing/ActiveLink';
render() {
return v('div', [
w(ActiveLink, { to: 'foo', params: { foo: 'bar' }, activeClasses: [ 'link-active' ]}, [ 'Link Text' ])
]);
}
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- vue路由篇(动态路由、路由嵌套)
- 小程序封装路由文件和路由方法,5种路由方法全解析
- Vue的路由及路由钩子函数
- gin 源码阅读(二)-- 路由和路由组
- vue router 路由鉴权(非动态路由)
- Flutter进阶:路由、路由栈详解及案例分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法设计与分析导论
R.C.T.Lee (李家同)、S.S.Tseng、R.C.Chang、Y.T.Tsai / 王卫东 / 机械工业 / 2008-1 / 49.00元
本书在介绍算法时,重点介绍用干设计算法的策略.非常与众不同。书中介绍了剪枝搜索、分摊分析、随机算法、在线算法以及多项式近似方案等相对较新的思想和众多基于分摊分析新开发的算法,每个算法都与实例一起加以介绍,而且每个例子都利用图进行详细解释。此外,本书还提供了超过400幅图来帮助初学者理解。本书适合作为高等院校算法设计与分析课程的高年级本科生和低年级研究生的教材,也可供相美科技人员和专业人七参考使用。一起来看看 《算法设计与分析导论》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
HSV CMYK 转换工具
HSV CMYK互换工具