Skip to content

路由系统

移动端路由由三部分组成:

  1. @uni-helper/vite-plugin-uni-pages 扫描页面文件,生成 src/pages.jsonvirtual:uni-pages
  2. 页面内通过 definePage() 声明页面配置。
  3. uni-mini-router 读取生成后的页面配置,提供编程式导航和路由守卫。

pages.json 如何生成?

项目没有手写完整的 pages.json。核心配置在两个地方:

文件作用
vite.config.ts注册 UniPages(),配置类型声明、分包目录和排除规则
pages.config.ts配置 globalStyletabBar 等全局页面配置

vite.config.ts 中的配置:

ts
UniPages({
  dts: "src/types/uni-pages.d.ts",
  subPackages: ["src/subPages"],
  exclude: ["**/components/**/*.*"],
})

含义:

配置说明
dts生成页面类型声明,方便 TypeScript 识别路由
subPackages分包页面目录,当前约定为 src/subPages
exclude排除组件目录,避免组件被误识别成页面

pages.config.ts 负责全局配置,例如导航栏、下拉刷新距离、TabBar 页面路径等。

注意

src/pages.json 是插件生成文件,文件中有 GENERATED BY UNI-PAGES 标记。新增页面或修改页面标题、布局时,优先改页面里的 definePage()pages.config.ts,不要手动维护生成结果。

新增页面怎么做?

src/pages/ 下创建页面文件即可,例如:

text
src/pages/work/user/index.vue

插件会自动生成页面路径:

text
/pages/work/user/index

页面配置写在 <script setup> 中的 definePage()

vue
<script setup lang="ts">
definePage({
  name: "user",
  style: {
    navigationBarTitleText: "用户管理",
  },
})
</script>

常用配置:

配置说明
name页面名称,便于识别和调试
style.navigationBarTitleText原生导航栏标题
style.navigationStyle导航栏样式,custom 表示自定义导航栏
layout页面布局,不写时使用默认布局
meta.requireAuth是否需要登录后访问,路由守卫会读取

需要登录的页面可以声明 meta.requireAuth

ts
definePage({
  name: "profile",
  style: { navigationBarTitleText: "个人资料" },
  meta: { requireAuth: true },
})

默认 layout 是什么?

项目使用 @uni-helper/vite-plugin-uni-layouts 管理布局,布局文件在:

text
src/layouts/
├── default.vue
└── tabbar.vue

默认规则:

页面配置实际布局适用场景
不写 layoutdefault普通页面、详情页、表单页
layout: "tabbar"tabbar首页、工作台、我的等底部 TabBar 页面
layout: false不套布局登录页、引导页、需要完全自定义结构的页面

普通页面不需要显式写 layout: "default"

ts
definePage({
  name: "user",
  style: { navigationBarTitleText: "用户管理" },
})

TabBar 页面需要显式声明:

ts
definePage({
  name: "home",
  style: { navigationStyle: "custom" },
  layout: "tabbar",
})

登录页如果不想套默认布局,可以显式关闭:

ts
definePage({
  name: "login",
  style: { navigationStyle: "custom", navigationBarTitleText: "" },
  layout: false,
})

建议

新增业务页面大多数情况下不用写 layout,只写 namestyle.navigationBarTitleText 即可。只有底部导航页面、登录页、全屏页或特殊页面才需要关心 layout

路由如何进入 uni-mini-router?

src/router/index.tsvirtual:uni-pages 读取生成后的页面配置:

ts
import { pages, subPackages } from "virtual:uni-pages";

项目会把主包和分包页面转换成 uni-mini-router 的路由表:

ts
function generateRoutes() {
  const routes = pages.map((page) => ({
    ...page,
    path: `/${page.path}`,
    meta: page.meta ?? undefined,
  }));

  subPackages?.forEach((subPackage) => {
    const subRoutes = subPackage.pages.map((page) => ({
      ...page,
      path: `/${subPackage.root}/${page.path}`,
      meta: page.meta ?? undefined,
    }));
    routes.push(...subRoutes);
  });

  return routes;
}

所以 definePage() 中的 meta 会透传到路由守卫中。

页面跳转

ts
// 保留当前页
uni.navigateTo({ url: "/pages/work/user/index" });

// 不保留当前页
uni.redirectTo({ url: "/pages/login/index" });

// 关闭所有页面
uni.reLaunch({ url: "/pages/index/index" });

// 编程式导航
router.push({ path: "/pages/mine/profile/index" });

参数传递

ts
uni.navigateTo({ url: `/pages/detail/index?id=${id}&type=${type}` });

onLoad((options) => {
  const { id, type } = options;
});

复杂对象不要直接拼到 URL,可以用全局状态、缓存或事件传递。

常见问题

问题原因处理方式
新页面跳转 404页面路径没有被插件扫描到确认文件在 src/pagessrc/subPages 下,且不在 components 目录
改了 definePage() 不生效生成文件或开发服务未刷新重启开发服务后再看生成的 src/pages.json
页面没有底部 TabBar没写 layout: "tabbar"TabBar 页面在 definePage() 中显式声明
页面出现不期望的外层布局默认套了 default 布局特殊页面可写 layout: false
路由守卫不生效没有配置 meta.requireAuthdefinePage() 中补充 meta: { requireAuth: true }

相关文档

基于 MIT 许可发布 · 如需部署协助或二开定制,请查看 支持与合作