因为对 Rxjs 的好感玩上了 Cycle.js,该系列用于记录使用该框架的一些笔记。本文记录使用 cyclic-router 来启动页面路由的过程。
# 启用页面路由
# cyclic-router (opens new window)
cyclic-router 是为 Cycle.js 设计的路由驱动。
- 安装模块:
npm install --save cyclic-router switch-path
这里面我们直接使用了官方推荐的switch-path
(opens new window),它提供路由匹配功能。
cyclic-router 在 V3 和 V4 版本是需要注入路由匹配模块,而在 V2 版本前是内置switch-path
,则不需要安装。
更多关于 cyclic-router 大家可以参考github--cyclic-router (opens new window)。
# 路由入口
我们将在启动主入口run()
的时候添加进路由:
import { run } from "@cycle/run";
import xs from "xstream";
import { makeDOMDriver } from "@cycle/dom";
import { makeRouterDriver } from "cyclic-router";
// 这里我们使用hash锚做路由,故使用createHashHistory替代createBrowserHistory
import { createHashHistory } from "history";
import switchPath from "switch-path"; // Required in v3, not required in v2 or below
import { AppComponent } from "./app";
import { LoginComponent } from "./login";
function main(sources) {
// 设置路由匹配规则
// 这里需要注意的是,必须有跟路由'/',否则将会报错:
const match$ = sources.router.define({
"/login": LoginComponent,
"/app": AppComponent,
"*": LoginComponent
});
// 匹配路由后处理
const page$ = match$.map(({ path, value }) => {
return value(
Object.assign({}, sources, {
router: sources.router.path(path)
})
);
});
return {
// 匹配路由后获取DOM作为流
DOM: page$.map(c => c.DOM).flatten(),
// 匹配路由后获取对应的router作为流,为空则设置''
// 然后flatten()将多个流抚平
router: xs.merge(
page$
.map(c => c.router)
.filter(x => x || "")
.flatten()
)
};
}
run(main, {
DOM: makeDOMDriver("#app"),
router: makeRouterDriver(createHashHistory(), switchPath) // v3
// router: makeRouterDriver(createHistory()) // <= v2
});
# 添加登陆页面跳转
这里我们添加一个登陆页面,主要用于登陆后路由跳转:
import { html } from "snabbdom-jsx";
import xs from "xstream";
export function LoginComponent(sources) {
const domSource = sources.DOM;
// 添加点击事件流
const loginClick$ = domSource.select("#submit").events("click");
// 添加html流
const loginView$ = xs.merge().startWith(
<form>
<h1>System</h1>
<div>
<input type="text" placeholder="username" />
</div>
<div>
<input type="password" placeholder="password" />
</div>
<div>
<button>Login</button>
</div>
</form>
);
return {
DOM: loginView$,
router: xs.merge(
// 点击事件将流转为'/app'
loginClick$.mapTo("/app")
)
};
}
跳转这个功能,本骚年可能尝试了无数遍,终于发现并不是登录页面的路由有问题,而是主入口的路由:
return {
DOM: page$.map(c => c.DOM).flatten(),
// 官方文档这个坑,这样写的话,是无法获取页面里面的router流了
// 这只是设置了个初始的流,匹配到'/other'路由
router: xs.of("/other")
};
经过深思熟虑之后,本骚年这样使用:
return {
DOM: page$.map(c => c.DOM).flatten(),
// 匹配路由后获取对应的router作为流,为空则设置''
// 然后flatten()将多个流抚平
router: xs.merge(
page$
.map(c => c.router)
.filter(x => x || "")
.flatten()
)
};
终于成功啦。
# 结束语
这节主要讲了使用 cyclic-router 来搭建路由,实现路由匹配和页面跳转等功能。
此处查看项目代码 (opens new window)
此处查看页面效果 (opens new window)