详细分析uni-app中的页面路由基本知识(附Demo)

前言

在 UniApp 中,页面和路由是用于导航应用内不同页面的机制

UniApp 提供一系列 API 来实现页面间的跳转、重定向、重载、切换 Tab 页面以及返回上一个页面等操作

以下主要围绕基本的几个API接口做阐述,更多的可以参考官网:uni-app中的页面和路由

1. uni.navigateTo

跳转到应用内的某个非 tabBar 页面,可以携带参数

跳转的页面会被存入历史栈中,用户可以通过 uni.navigateBack 返回

参数说明:

  • url (String):跳转的目标页面路径,可以携带参数
  • events (Object): 页面间通信使用的事件通道
  • success (Function):接口调用成功的回调函数
  • fail (Function): 接口调用失败的回调函数
  • complete (Function):接口调用结束的回调函数

代码示例:

uni.navigateTo({
  url: '/pages/detail/detail?id=123', // 跳转页面路径,携带参数 id=123
  success: function() {
    console.log("跳转成功");
  },
  fail: function() {
    console.log("跳转失败");
  }
});

2. uni.redirectTo

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

新的页面不会被存入历史栈中,无法通过 uni.navigateBack 返回(中过一次坑,索性记住了)

参数说明:

  • url (String):目标页面路径
  • success (Function): 成功回调
  • fail (Function):失败回调
  • complete (Function):完成回调

代码示例:

uni.redirectTo({
  url: '/pages/login/login', // 跳转到登录页面
  success: function() {
    console.log("重定向成功");
  },
  fail: function() {
    console.log("重定向失败");
  }
});

3. uni.reLaunch

关闭所有页面,重新打开应用内的某个页面

适用于需要彻底重启应用导航的场景,例如登录后重启整个应用

参数说明:

  • url (String):目标页面路径
  • success (Function): 成功回调
  • fail (Function):失败回调
  • complete (Function):完成回调
uni.reLaunch({
  url: '/pages/home/home', // 重新打开首页
  success: function() {
    console.log("应用重启并跳转成功");
  },
  fail: function() {
    console.log("跳转失败");
  }
});

4. uni.switchTab

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

适用于应用含有多个 tabBar 页面时的导航

参数说明:

  • url (String):目标 tabBar 页面路径
  • success (Function): 成功回调
  • fail (Function):失败回调
  • complete (Function):完成回调
uni.switchTab({
  url: '/pages/tab/home', // 跳转到 tabBar 页面的首页
  success: function() {
    console.log("切换 Tab 成功");
  },
  fail: function() {
    console.log("切换 Tab 失败");
  }
});

5. uni.navigateBack

关闭当前页面,返回上一层页面,支持传递返回的层级

参数说明:delta (Number)
返回的页面层级,默认值为 1,即返回上一层

uni.navigateBack({
  delta: 1, // 返回上一层页面
  success: function() {
    console.log("返回成功");
  },
  fail: function() {
    console.log("返回失败");
  }
});

6. 页面和路由

<template>
  <view class="container">
    <button @click="goToDetail">跳转到详情页面</button>
    <button @click="redirectToLogin">重定向到登录页面</button>
    <button @click="switchToTab">切换到 Tab 页面</button>
    <button @click="relaunchApp">重新启动应用并跳转</button>
  </view>
</template>

<script>
export default {
  methods: {
    goToDetail() {
      uni.navigateTo({
        url: '/pages/detail/detail?id=456',
        success: () => {
          console.log('成功跳转到详情页');
        }
      });
    },
    redirectToLogin() {
      uni.redirectTo({
        url: '/pages/login/login',
        success: () => {
          console.log('成功重定向到登录页');
        }
      });
    },
    switchToTab() {
      uni.switchTab({
        url: '/pages/tab/home',
        success: () => {
          console.log('成功切换到 Tab 页面');
        }
      });
    },
    relaunchApp() {
      uni.reLaunch({
        url: '/pages/home/home',
        success: () => {
          console.log('成功重启应用并跳转');
        }
      });
    }
  }
}
</script>

详情页:

<template>
  <view class="container">
    <text>这是详情页面,参数 ID 为 {{ id }}</text>
    <button @click="goBack">返回上一页</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      id: ''
    };
  },
  onLoad(options) {
    this.id = options.id; // 获取页面跳转时传递的参数
  },
  methods: {
    goBack() {
      uni.navigateBack({
        delta: 1, // 返回上一层
        success: () => {
          console.log('成功返回上一页');
        }
      });
    }
  }
}
</script>

7. 彩蛋

7.1 tabBar知识

在 UniApp 中,tabBar 页面和非 tabBar 页面是指不同类型的页面布局方式,具体体现在导航方式上

  1. tabBar 页面

应用底部带有 固定导航栏(即 tabBar)的页面,这种页面结构允许用户通过底部的导航栏在多个页面之间快速切换
tabBar 是 全局设置的,始终固定在应用的底部,并且通常包含多个页面的入口

主要特点有如下:

  • 位置固定:tabBar 始终位于应用界面的底部,并且不可隐藏
  • 快速切换:用户可以通过点击 tabBar 上的图标在不同页面间快速切换
  • 互相独立:每个 tabBar 页面是相互独立的,切换时不会记录页面历史栈,无法通过 uni.navigateBack 返回之前的 tabBar 页面
  • 全局配置:在 pages.json 文件中统一配置

示例配置 (pages.json):

{
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "static/home.png",
        "selectedIconPath": "static/home_selected.png"
      },
      {
        "pagePath": "pages/user/user",
        "text": "用户",
        "iconPath": "static/user.png",
        "selectedIconPath": "static/user_selected.png"
      }
    ]
  }
}

list 数组定义 tabBar 上显示的页面(如首页、用户页面)
每个页面的 pagePath 必须对应应用中的实际页面路径

tabBar 页面切换示例:

uni.switchTab({
  url: '/pages/home/home',
  success: function() {
    console.log("成功切换到首页");
  }
});
  1. 非 tabBar 页面
    非 tabBar 页面是指不属于底部导航栏的页面,这些页面一般通过其他页面跳转(例如 uni.navigateTo)进入

非 tabBar 页面可以被加入历史栈,允许用户返回之前访问的页面

主要特点有如下:

  • 历史栈管理:非 tabBar 页面会记录在历史栈中,用户可以通过 uni.navigateBack 返回到前一个页面
  • 自由跳转:这些页面通常用于展示详细内容、用户设置等不常用的页面,可以通过按钮、链接等进行跳转
  • 没有固定导航栏:这些页面没有底部的导航栏(tabBar),也不会出现在全局导航中

非 tabBar 页面跳转示例:

uni.navigateTo({
  url: '/pages/detail/detail?id=123',
  success: function() {
    console.log('跳转成功');
  }
});
  1. 区别总结
特性tabBar 页面非 tabBar 页面
位置带有底部的固定导航栏没有固定导航栏
切换方式通过 tabBar 快速切换,使用 uni.switchTab通过页面跳转,使用 uni.navigateTo、uni.redirectTo
历史记录不记录历史栈,不能通过 uni.navigateBack 返回记录历史栈,可以通过 uni.navigateBack 返回
场景常用于应用的主要页面(如首页、分类、个人中心)常用于详细页面或次要页面(如详情页、设置页面)

使用建议

  1. tabBar 页面 适合放置应用的主导航页面,如首页、分类页、个人中心等核心功能页面,方便用户快速切换
  2. 非 tabBar 页面 适合用来展示详细内容、执行某些操作或提供额外功能

7.2 EventChannel知识

EventChannel 是 UniApp 提供的页面间通信机制,主要用于在页面跳转时传递复杂数据(如函数、对象等)和在跳转后保持页面之间的通信

例如,页面 A 跳转到页面 B 时,可以通过 EventChannel 传递消息,B 页面可以接收消息,并且可以在 B 页面处理后将数据返回给 A 页面

核心功能

  • 发送数据:通过 eventChannel.emit 方法发送数据到目标页面

  • 接收数据:通过 eventChannel.on 方法在目标页面接收数据

  • 获取 EventChannel:通过 getOpenerEventChannel 方法获取来源页面的 eventChannel

  • emit(eventName, data):发送数据到目标页面。
    eventName (String):事件名称
    data (Any):要发送的数据

  • on(eventName, callback): 监听并接收来自来源页面的数据
    eventName (String):事件名称
    callback (Function):事件触发时的回调,接收发送的数据

  • getOpenerEventChannel():获取来源页面的 EventChannel 对象

使用 EventChannel 的 Demo

  1. 页面 A:发送消息到页面 B
    页面 A 跳转到页面 B,并通过 EventChannel 向 B 页面发送数据
    B 页面处理后可以通过 EventChannel 返回数据
<template>
  <view class="container">
    <button @click="goToDetail">跳转到详情页面并发送数据</button>
  </view>
</template>

<script>
export default {
  methods: {
    goToDetail() {
      const that = this;
      uni.navigateTo({
        url: '/pages/detail/detail', // 跳转到详情页面
        events: {
          // 事件监听,等待详情页返回的数据
          acceptDataFromDetailPage: function(data) {
            console.log('接收到详情页返回的数据:', data);
            uni.showToast({
              title: `详情页返回数据: ${data}`,
              icon: 'none'
            });
          }
        },
        success: function (res) {
          // 通过 EventChannel 发送数据到详情页
          res.eventChannel.emit('sendDataToDetailPage', { id: 123, name: '张三' });
        }
      });
    }
  }
}
</script>
  1. 页面 B (detail.vue)
<template>
  <view class="container">
    <text>这是详情页面</text>
    <button @click="sendBack">返回上一页并传递数据</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      id: '',
      name: ''
    };
  },
  onLoad() {
    // 获取来源页面的 EventChannel
    const eventChannel = this.getOpenerEventChannel();
    
    // 监听来源页面发送的数据
    eventChannel.on('sendDataToDetailPage', (data) => {
      console.log('收到页面 A 传来的数据:', data);
      this.id = data.id;
      this.name = data.name;
    });
  },
  methods: {
    sendBack() {
      // 通过 EventChannel 向来源页面发送数据
      const eventChannel = this.getOpenerEventChannel();
      eventChannel.emit('acceptDataFromDetailPage', `数据已处理,ID 为 ${this.id}`);
      
      // 返回上一页
      uni.navigateBack();
    }
  }
}
</script>

具体逻辑如下:

当用户点击按钮时,页面 A 通过 uni.navigateTo 跳转到页面 B
跳转时,使用 events 属性定义了一个事件 acceptDataFromDetailPage,用于接收页面 B 的返回数据
在 success 回调中,使用 res.eventChannel.emit(‘sendDataToDetailPage’, …) 向 B 页面发送数据

在页面 B:
使用 getOpenerEventChannel() 获取 A 页面的 EventChannel 对象
使用 eventChannel.on(‘sendDataToDetailPage’, …) 来接收 A 页面传来的数据,并将数据展示在页面上
点击按钮后,使用 eventChannel.emit(‘acceptDataFromDetailPage’, …) 将处理后的数据发送回页面 A,随后返回上一页

EventChannel 适用于需要在页面跳转过程中传递复杂数据或需要双向通信的场景
通过 emit 和 on 方法,页面间可以方便地进行数据的传递和处理

7.3 总结

  • navigateTo, redirectTo 只能打开非 tabBar 页面
  • switchTab 只能打开 tabBar 页面
  • reLaunch 可以打开任意页面
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar
  • 不能在首页 onReady 之前进行页面跳转
  • H5端页面刷新之后页面栈会消失,此时navigateBack不能返回,如果一定要返回可以使用history.back()导航到浏览器的其他历史记录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值