Skip to content

导航

普通跳转使用 <elf-link>。它是 <elf-router-link> 的别名,会渲染无障碍链接;它只拦截普通左键点击,并保留修饰键点击与浏览器的原生行为。

模板中的链接

html
<nav>
  <elf-link to="/">首页</elf-link>
  <elf-link :to=${{ name: "user", params: { id: "42" } }}>个人资料</elf-link>
  <elf-link :to=${{ name: "search", query: { q: "router", page: 2 } }}>
    搜索
  </elf-link>
  <elf-link to="/login" replace>登录</elf-link>
</nav>

replace 会替换当前历史记录。active-classexact-active-class 可覆盖路由器全局默认值;aria-current-value 可设置激活链接的 aria-current 值(默认 page)。父级链接在子路由中也会激活;精确激活还要求路由记录和参数完全一致。

html
<elf-link to="/settings" active-class="selected" exact-active-class="selected-exact"> 设置 </elf-link>

在组件代码中导航

push() 新增一条历史记录,replace() 替换当前记录。两者都支持字符串路径、路径对象和命名 location,并返回 undefined 或导航失败对象。

ts
import { useRouter } from "@elfui/router";

const router = useRouter();

async function saveUser(id: string) {
  await api.save();
  const result = await router?.push({
    name: "user",
    params: { id },
    query: { notice: "saved" },
    hash: "#activity",
    state: { source: "editor" }
  });
}

router?.replace({ path: "/login", query: { redirect: "/settings" } });
router?.back();
router?.forward();
router?.go(-2);

state 会随浏览器历史记录保存,可通过 history.state 读取,不会写进 URL。若要在当前 URL 上重新执行守卫和懒加载解析,可传入 force: true

ts
await router?.push({ path: "/reports", force: true });

只解析,不跳转

resolve() 不会改变当前路由。它适合预览目标、生成预先计算的链接,或相对于当前路由解析字符串。

ts
const preview = router?.resolve({ name: "user", params: { id: "7" } });
console.log(preview?.href); // base 为 /console 时:/console/users/7
console.log(preview?.fullPath); // /users/7

const sibling = router?.resolve("../settings");

处理被取消的导航

守卫可以中止导航;一次新的导航也可能取消尚未完成的旧导航。不使用 force 重复当前 URL 同样属于失败。这些情况不会抛出异常,检查返回值即可。

ts
import { isNavigationFailure, NavigationFailureType } from "@elfui/router";

const result = await router?.push("/settings");

if (isNavigationFailure(result, NavigationFailureType.aborted)) {
  toast("请先保存或放弃当前修改。");
}

当前路由与 query 工具

useRoute() 返回稳定、只读的 facade。在响应式代码中读取它的属性,不需要在每次导航后重新获取。

ts
import { useRoute } from "@elfui/router";

const route = useRoute();
// route.params.id、route.query.tab、route.hash、route.meta、route.matched

query 的值是字符串、null(没有 = 的键)或重复键形成的数组。parseQuery()stringifyQuery() 可让路由外代码复用相同的 URL 规则。

ts
import { parseQuery, stringifyQuery } from "@elfui/router";

parseQuery("?tag=elf&tag=router&draft");
// { tag: ["elf", "router"], draft: null }

stringifyQuery({ page: 2, tag: ["elf", "router"], draft: null });
// "?page=2&tag=elf&tag=router&draft"

自定义链接

设计系统控件可使用无头的 useLink(),或 <elf-link custom> 的默认作用域插槽。二者都会提供 href、激活状态与 navigate()

ts
import { useLink } from "@elfui/router";

const link = useLink({ to: { name: "settings" }, replace: true });
// 绑定 link.href,并在自定义按钮中调用 link.navigate()。