因为对 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)

部分文章中使用了一些网站的截图,如果涉及侵权,请告诉我删一下谢谢~
温馨提示喵