uni-app中路由的使用

在 uni-app 中,路由指的是页面之间的跳转与导航机制。它基于页面栈进行管理,支持声明式和编程式两种用法。下面详细介绍路由的配置、跳转方式、传参、页面栈管理等核心内容。

一、路由配置:pages.json

所有页面路径必须在 pages.jsonpages 数组中声明,才能被访问。

复制代码
{
  "pages": [
    {
      "path": "pages/index/index",      // 页面路径
      "style": { ... }                  // 页面样式配置
    },
    {
      "path": "pages/detail/detail",
      "style": { ... }
    }
  ],
  "tabBar": { ... }                     // 底部选项卡配置
}
  • pages 数组的第一项为首页。

  • 如果页面是 tabBar 页面,则需要在 tabBar 中配置对应的 pagePath

二、路由跳转方式

uni-app 提供了两种跳转方式:声明式 (使用 <navigator> 组件)和 编程式(调用 API)。

1. 声明式跳转

使用 <navigator> 组件,类似 HTML 中的 <a> 标签。

复制代码
<!-- 普通跳转,保留当前页面 -->
<navigator url="/pages/detail/detail" hover-class="navigator-hover">
  跳转到详情页
</navigator>

<!-- 重定向跳转,关闭当前页面 -->
<navigator url="/pages/detail/detail" open-type="redirect">
  重定向到详情页
</navigator>

<!-- 跳转到 tabBar 页面 -->
<navigator url="/pages/user/user" open-type="switchTab">
  跳转到我的
</navigator>

open-type 的可选值:

  • navigate:保留当前页面,跳转到非 tabBar 页面(默认)。

  • redirect:关闭当前页面,跳转到非 tabBar 页面。

  • switchTab:跳转到 tabBar 页面,关闭所有非 tabBar 页面。

  • reLaunch:关闭所有页面,跳转到任意页面(通常用于登录后跳转)。

  • navigateBack:返回上一页或多级页面(需要配合 delta 属性)。

2. 编程式跳转

通过 uni 提供的 API 进行跳转,更灵活,可以在 JavaScript 中调用。

uni.navigateTo

保留当前页面,跳转到应用内的某个非 tabBar 页面。

复制代码
uni.navigateTo({
  url: '/pages/detail/detail?id=123&name=uni-app'
});
uni.redirectTo

关闭当前页面,跳转到应用内的某个非 tabBar 页面。

复制代码
uni.redirectTo({
  url: '/pages/detail/detail'
});
uni.switchTab

跳转到 tabBar 页面,并关闭所有非 tabBar 页面。

复制代码
uni.switchTab({
  url: '/pages/user/user'
});
uni.reLaunch

关闭所有页面,打开到应用内的某个页面(常用于登录后跳转首页)。

复制代码
uni.reLaunch({
  url: '/pages/index/index'
});
uni.navigateBack

返回上一页或多级页面。

复制代码
// 返回上一页
uni.navigateBack();

// 返回上两页
uni.navigateBack({
  delta: 2
});

三、路由传参与接收

1. 传递参数

参数通过 url 的查询字符串传递(?key=value),多个参数用 & 连接。

复制代码
uni.navigateTo({
  url: '/pages/detail/detail?id=123&title=Hello'
});

如果需要传递对象等复杂数据,可以先使用 encodeURIComponent 转为字符串。

复制代码
let data = { id: 123, name: 'uni-app' };
uni.navigateTo({
  url: '/pages/detail/detail?data=' + encodeURIComponent(JSON.stringify(data))
});

2. 接收参数

在目标页面的 onLoad 生命周期函数中接收,参数以对象形式传入。

复制代码
export default {
  onLoad(options) {
    console.log(options.id);      // 123
    console.log(options.title);   // Hello

    // 如果传递了 JSON 数据
    if (options.data) {
      let data = JSON.parse(decodeURIComponent(options.data));
      console.log(data);
    }
  }
}

注意onLoad 只会在页面第一次加载时触发,如果页面已存在于页面栈中且使用 navigateTo 打开,不会重新触发 onLoad,此时可以通过其他方式(如 $on/$emit 或全局变量)传递新数据。

四、页面栈管理

uni-app 使用 页面栈 来管理页面,遵循"先进后出"的原则。常用 API 对应的页面栈变化:

API 页面栈变化
navigateTo 新页面入栈
redirectTo 当前页面出栈,新页面入栈
navigateBack 当前页面出栈(可指定出栈层数)
switchTab 清空所有非 tabBar 页面,跳转到指定 tabBar 页
reLaunch 清空所有页面,新页面入栈

可以通过 getCurrentPages() 获取当前页面栈实例数组,数组中第一个元素为首页,最后一个为当前页。

复制代码
let pages = getCurrentPages();       // 获取页面栈
let currentPage = pages[pages.length - 1]; // 当前页面实例
let prevPage = pages[pages.length - 2];     // 上一个页面实例

借助页面实例,可以在返回时传递数据给上一页:

复制代码
// 在 B 页面
let pages = getCurrentPages();
let prevPage = pages[pages.length - 2];
prevPage.$data.someData = '需要传递的数据';
uni.navigateBack();

五、路由拦截与权限控制

虽然 uni-app 没有内置全局路由守卫,但可以通过在 App.vueonLaunch 中监听路由跳转,或封装统一的跳转函数来实现权限控制。

简单封装示例

复制代码
// utils/router.js
function navigateTo(url, needLogin = false) {
  if (needLogin && !uni.getStorageSync('token')) {
    uni.navigateTo({
      url: '/pages/login/login'
    });
    return;
  }
  uni.navigateTo({ url });
}

export default { navigateTo };

然后在页面中使用:

复制代码
import router from '@/utils/router';
router.navigateTo('/pages/detail/detail', true);

六、注意事项

  1. 页面路径必须已注册 :跳转的页面需在 pages.jsonpages 中定义。

  2. tabBar 页面限制navigateToredirectTo 不能跳转到 tabBar 页面,必须使用 switchTab

  3. 页面栈最大深度navigateTo 最多可打开 10 层页面,超出会触发失败回调。

  4. H5 兼容性 :在 H5 端,如果使用了 history 模式路由,跳转时 url 中的 # 需注意处理;uni-app 推荐使用 hash 模式。

  5. 动画效果 :可通过 animationTypeanimationDuration 自定义页面切换动画(App 端支持)。

  6. 页面生命周期 :路由跳转会触发相应页面的生命周期(onLoadonShowonHide 等),需合理使用。


相关推荐
程序员陆业聪2 小时前
上下文工程与提示词工程:拆解 OpenClaw 是如何「喂养」大模型的
前端
wuhen_n2 小时前
初识Function Calling:让AI学会“调用工具”
前端·vue.js·ai编程
wuhen_n2 小时前
异步组件与 Suspense:如何优雅地处理加载状态并优化首屏加载?
前端·javascript·vue.js
万物得其道者成2 小时前
uni-app App 端不支持 SSE?用 renderjs + XHR 流式解析实现稳定输出
前端·javascript·uni-app
恋猫de小郭2 小时前
Flutter 的 build_runner 已经今非昔比,看看 build_runner 2.13 有什么特别?
android·前端·flutter
yuhaiqiang2 小时前
AI 正在偷走大家的独立思考能力……
前端·后端·面试
不会写DN2 小时前
[特殊字符] JS Date 对象8大使用场景
开发语言·前端·javascript
WeirdoPrincess2 小时前
iOS 打包签名资料准备指南(HBuilderX / uni-app)
ios·uni-app
bearpping10 小时前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx