更新记录

1.0.0(2026-09-29)

初次上线


平台兼容性

uni-app x(5.25)

Chrome Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序
- - 5.0 1.0.0 17 1.0.0 - -

其他

多语言 暗黑模式 宽屏模式
× √ ×

uni-app x 原生路由

让每一次页面切换,都自然衔接。

面向 iOS 与 Android 的页面导航与交互插件。九种页面转场、跟手返回、三种弹窗形态,以及浅色与深色外观,为应用中的进入、返回、展开与收起,带来更细腻的体验。

版本 1.0.0 · iOS / Android · uni-app x

使用教程:快速接入 · 常用操作 · 常见问题


真机交互 · 先看体验

动画的节奏、手势的反馈、弹窗的展开与回弹,直接看真机操作。

iOS 真机演示 Android 真机演示
在 iPhone 上感受交互 在安卓设备上感受交互
▶ 观看 iOS 真机交互视频 ▶ 观看 Android 真机交互视频

视频在哔哩哔哩打开。建议结合示例项目,在自己的设备上体验完整操作。


六项核心体验

能力 体验
九种页面转场 从轻快滑动到立体翻转,为不同页面选择合适的出场方式。
跟手返回 从页面左侧边缘滑动,完成返回;取消时回到当前页面。
三种弹窗形态 半屏、遮罩、卡片,承载不同层次的内容与操作。
保留当前进度 返回仍保留的上一页时,继续之前的输入与浏览位置。
浅色与深色外观 切换导航栏与弹窗外观,配合业务页面形成统一主题。
可调动画节奏 按场景调整进入与返回时长,也支持无动画切换。

页面转场 · 让内容有自己的节奏

日常导航可以简洁轻快,重点内容也可以拥有更鲜明的层次。九种转场效果,覆盖不同的视觉表达。

转场效果 视觉表现
横向滑动 沿水平方向自然切入,适合日常页面导航。
景深推进 通过前后层次变化,呈现进入内容的纵深感。
层叠上浮 页面向上浮现,强调新内容的层级。
斜向旋入 带有倾斜角度的进入方式,让切换更有动势。
立体翻转 以翻转效果呈现页面之间的转换。
中心展开 从中心展开内容,集中视觉注意力。
交叉淡入 以柔和的透明度变化衔接页面。
顶部落入 从上方进入,形成明确的方向感。
纵向翻入 以纵向翻转带出新的页面层次。

进入与返回的动画时长可按需调整。需要即时响应的场景,也可以关闭动画。

弹窗交互 · 恰到好处地展开

半屏弹窗

先展示重点,再展开更多。支持半屏与展开状态之间的切换,以及下拉关闭,适合选项面板、内容预览和轻量编辑。

遮罩弹窗

让注意力聚焦到当前操作。适合信息提示、操作确认和短内容展示;示例提供点击空白区域关闭的交互。

卡片弹窗

以独立卡片承载更完整的内容。拖动顶部区域时,卡片跟随手势变化,松手后关闭或回弹,适合详情预览与临时操作面板。

支持多层打开,逐层返回。 关闭上层弹窗后,可以继续操作下层内容;下层仍打开时,保留已输入的文字和当前状态。

不同平台的手势与外观细节有所差异,请结合对应平台的真机视频与示例体验。

返回之后 · 接着刚才的操作

打开详情,再回到列表;进入下一页,再继续填写;临时打开弹窗,处理完成后回到原处。

只要上一页仍保留在当前导航流程中,就可以继续原来的输入、滚动位置和页面操作。页面关闭或应用重启后的数据保存,仍由业务自行处理。

深浅外观 · 与应用风格协调

支持浅色与深色外观切换,覆盖导航栏和弹窗的相关外观。

示例项目提供两种主题供体验。接入自己的项目时,业务页面的文字、背景和组件颜色需要同步适配。


适合哪些场景

  • 内容浏览:列表进入详情,再返回原来的浏览位置。
  • 表单与编辑:临时查看其他页面后,继续尚未完成的输入。
  • 选项与筛选:通过半屏面板完成选择,保留当前页面的上下文。
  • 详情与预览:使用卡片展示补充内容,再回到原来的操作。
  • 多层操作:在弹窗内继续打开弹窗,完成后逐层返回。

使用环境

项目 要求
开发框架 uni-app x
开发工具 HBuilderX 5.26,请使用此版本接入
渲染模式 VDOM
iOS iOS 15.0 及以上
Android Android 5.0 及以上
其他平台 暂不支持 Web、小程序、HarmonyOS 和 Vapor

系统版本要求表示最低接入条件,不代表全部机型均已完成测试。正式使用前,请在目标设备和实际业务页面中验证。

快速接入

只想先体验效果? 用 HBuilderX 5.26 打开示例项目,选择 VDOM,运行到 iOS 或 Android 真机,点击「开始体验」即可。首次运行需要编译原生插件;使用自定义基座时,需要制作包含本插件的基座。

接入正式项目时,应用启动后自动进入业务首页,不需要用户点击“开始体验”。 按下面 6 步配置,即可完成“启动 App → 自动进入首页 → 打开详情 → 返回首页”的流程。

自动启动代码放在项目首个页面的 onReady 中,页面就绪后执行一次。不要直接放进 App.uvue 的 onLaunch,也不要放进会反复执行的 onShow。

第 1 步:导入插件

从插件市场导入到自己的 uni-app x 项目,确认项目中存在:

uni_modules/kongbai-native-route

请保留插件目录名,不要自行改名。插件本身不依赖示例项目的 common 目录,也无需另外安装第三方库。

第 2 步:配置 vite.config.js

在项目根目录创建或修改 vite.config.js:

import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import nativeRouter from './uni_modules/kongbai-native-route/build/plugin.cjs'

export default defineConfig({
  plugins: [uni(), nativeRouter()]
})

已有配置时不要整份覆盖。 保留原有配置,只补充 nativeRouter 的导入,并在现有 plugins 数组中追加 nativeRouter();uni() 不要重复添加。

第 3 步:Android 补充 main.uts 配置

只做 iOS 可以跳过这一步。 同时支持两端时保留下面的条件编译即可。

下面是最小 main.uts 示例。已有初始化代码时,请合并导入、nativeRouterPageMixin 和 app.mixin(...),不要删除自己的代码。

import App from './App.uvue'
import { createSSRApp } from 'vue'
// #ifdef APP-ANDROID
import { defineMixin } from 'vue'
import { KBAndroidPageTransition } from 'uts.sdk.modules.kongbaiNativeRoute'
import View from 'android.view.View'

const nativeRouterPageMixin = defineMixin({
  onLoad() {
    const page = this.$page
    KBAndroidPageTransition.preparePage(page.route, () : View | null => page.getAndroidView())
  }
})
// #endif

export function createApp() {
  const app = createSSRApp(App)
  // #ifdef APP-ANDROID
  app.mixin(nativeRouterPageMixin)
  // #endif
  return { app }
}

这段是 Android 接入所需的固定配置,按示例添加即可。

第 4 步:配置启动页与业务页面

下面用一个启动页和两个业务页面说明。已有启动页可以直接复用,无需额外制作“开始体验”页面;启动页负责自动进入业务首页,用户不需要手动操作。

页面文件 作用
pages/index/index.uvue 应用启动页,就绪后自动打开业务首页
pages/home/home.uvue 用户实际使用的业务首页
pages/detail/detail.uvue 从首页打开的详情页

新项目的最小 pages.json 如下。启动页放在 pages 数组第一项;已有项目保留原有配置,将下面的路径替换为自己的路径。

{
  "pages": [
    {
      "path": "pages/index/index",
      "style": { "navigationStyle": "custom" }
    },
    {
      "path": "pages/home/home",
      "style": { "navigationBarTitleText": "首页" }
    },
    {
      "path": "pages/detail/detail",
      "style": { "navigationBarTitleText": "详情" }
    }
  ]
}

注意:pages.json 的路径不带开头的 /,调用插件时的页面地址需要带 /。两处都不写 .uvue 后缀。

第 5 步:把下面代码放进对应页面

① 自动启动:放在项目首个页面中

下面以 pages/index/index.uvue 为例。页面准备好后自动打开首页,正常情况下不显示启动按钮;仅在打开失败时提供重试。

当前版本要求启动页与目标业务首页是不同的页面地址,不能让启动页打开它自己。这是一次性接入配置,不需要把测试项目的介绍页面或按钮搬进自己的产品。

<template>
  <view class="startup-page">
    <view v-if="failed">
      <text>暂时无法进入,请重试</text>
      <button :disabled="busy" @click="openHome">重新打开</button>
    </view>
  </view>
</template>

<script setup lang="uts">
import { ref } from 'vue'
import { startNativeRouter } from '@/uni_modules/kongbai-native-route'

const busy = ref(false)
const failed = ref(false)
let started = false

onReady(() => {
  openHome()
})

function openHome() {
  if (busy.value || started) return
  busy.value = true
  failed.value = false
  startNativeRouter('/pages/home/home', (raw : string) => {
    busy.value = false
    const result = JSON.parse<UTSJSONObject>(raw)
    started = result?.getBoolean('ok') == true
    failed.value = !started
  })
}
</script>

<style>
.startup-page { flex: 1; background-color: #FFFFFF; justify-content: center; align-items: center; }
</style>

如果应用需要先恢复登录状态或读取启动配置,将 onReady 中的直接调用改为“等待初始化完成后调用 openHome()”,按业务需要将目标地址换成首页或登录页。确保初始化完成、首个页面就绪这两个条件都满足后再启动;启动期间不要同时调用其他导航接口或打开弹窗。

② 首页:pages/home/home.uvue

进入导航后,使用从插件导入的 navigateTo 打开详情。示例同时传入商品编号 id=1。

<template>
  <view>
    <button :disabled="busy" @click="openDetail">查看详情</button>
  </view>
</template>

<script setup lang="uts">
import { ref } from 'vue'
import { navigateTo } from '@/uni_modules/kongbai-native-route'

const busy = ref(false)

function openDetail() {
  if (busy.value) return
  busy.value = true
  navigateTo({
    url: '/pages/detail/detail?id=1',
    animationType: 'slide',
    animationDuration: 340,
    fail: (_ : string) => {
      uni.showToast({ title: '打开失败,请重试', icon: 'none' })
    },
    complete: (_ : string) => { busy.value = false }
  })
}

</script>

③ 详情页:pages/detail/detail.uvue

在 onLoad 中接收参数,点击按钮返回首页,也可以体验左侧边缘手势返回。

<template>
  <view>
    <text>当前商品编号:{{ itemId }}</text>
    <button :disabled="busy" @click="goBack">返回首页</button>
  </view>
</template>

<script setup lang="uts">
import { ref } from 'vue'
import { navigateBack } from '@/uni_modules/kongbai-native-route'

const itemId = ref('')
const busy = ref(false)

onLoad((options : UTSJSONObject) => {
  itemId.value = options.getString('id') ?? ''
})

function goBack() {
  if (busy.value) return
  busy.value = true
  navigateBack({
    fail: (_ : string) => {
      uni.showToast({ title: '返回失败,请重试', icon: 'none' })
    },
    complete: (_ : string) => { busy.value = false }
  })
}
</script>

上面的 navigateTo、navigateBack 均从本插件导入,不要写成 uni.navigateTo 或 uni.navigateBack。业务页面直接使用公开接口即可,无需复制示例的公共封装。

第 6 步:重新编译并运行

停止当前运行任务,再运行到 iOS 或 Android 真机。使用自定义基座时,先重新制作包含本插件的基座。

启动 App 后应自动进入业务首页,无需点击启动按钮。然后点击 「查看详情」→「返回首页」,详情页应显示商品编号 1,返回后继续停留在业务首页。

这条流程跑通后,再换成自己的页面内容。以上调用代码适用于 App;如果项目还需要编译到其他端,请用 APP-IOS / APP-ANDROID 条件编译隔离这些导入与调用。


常用操作

更换转场与动画时长

修改 navigateTo 的 animationType 即可。下表左侧就是代码中使用的值:

animationType 效果
slide 横向滑动
depth 景深推进
lift 层叠上浮
tilt 斜向旋入
flip 立体翻转
portal 中心展开
fade 交叉淡入
drop 顶部落入
swing 纵向翻入
import { navigateTo } from '@/uni_modules/kongbai-native-route'

function openWithFade() {
  navigateTo({
    url: '/pages/detail/detail?id=1',
    animationType: 'fade',
    animationDuration: 550
  })
}

animationDuration 单位是毫秒,范围为 0~3000;0 表示无动画。不填时,横向滑动默认 340 毫秒,其余效果默认 550 毫秒。

普通页面返回时默认沿用进入时长,也可以单独指定:

import { navigateBack } from '@/uni_modules/kongbai-native-route'

function goBackQuickly() {
  navigateBack({ animationDuration: 200 })
}

传递页面参数

在页面地址后加查询参数即可,目标页面用 onLoad 读取。传递中文、空格等内容时,先用 encodeURIComponent 编码:

import { navigateTo } from '@/uni_modules/kongbai-native-route'

function openProduct() {
  navigateTo({
    url: '/pages/detail/detail?id=1&name=' + encodeURIComponent('示例商品')
  })
}

目标页面在自己的 onLoad 中使用 options.getString('name') 获取名称。地址必须是已注册的本地页面,不能传外部网址。

打开半屏、遮罩或卡片弹窗

先准备弹窗页面,再调用打开接口。 最容易上手的方式是复用示例项目已经配好的弹窗:

  1. 将示例的 pages/presentation 目录复制到自己的项目。
  2. 同时复制该页面引用的 common/router.uts、common/theme.uts 和 common/demo.css。自己的项目已有同名文件时请合并,避免覆盖。
  3. 在 pages.json 的 pages 数组中追加下面这一个页面对象。
{
  "path": "pages/presentation/presentation",
  "style": {
    "navigationStyle": "custom",
    "navigationBarTitleText": "弹窗",
    "backgroundColor": "transparent"
  }
}

在已经打开的业务页面中,把按钮绑定到以下任意一个函数:

import { presentNativePage } from '@/uni_modules/kongbai-native-route'

function showModalResult(raw : string) {
  const result = JSON.parse<UTSJSONObject>(raw)
  if (result?.getBoolean('ok') != true) {
    uni.showToast({ title: '弹窗打开失败,请重试', icon: 'none' })
  }
}

function openSheet() {
  presentNativePage('/pages/presentation/presentation?mode=sheet', 'sheet', showModalResult)
}

function openOverlay() {
  presentNativePage('/pages/presentation/presentation?mode=overlay', 'overlay', showModalResult)
}

function openCard() {
  presentNativePage('/pages/presentation/presentation?mode=card', 'card', showModalResult)
}

第二个参数决定弹窗类型:sheet 是半屏,overlay 是遮罩,card 是卡片。地址里的 mode 是示例页面用来切换内容布局的参数,按上面的对应关系填写即可。

关闭最上层弹窗:

import { dismissNativePage } from '@/uni_modules/kongbai-native-route'

function closeModal() {
  dismissNativePage((raw : string) => {
    const result = JSON.parse<UTSJSONObject>(raw)
    if (result?.getBoolean('ok') != true) {
      uni.showToast({ title: '关闭失败,请重试', icon: 'none' })
    }
  })
}

换成自己的弹窗内容时,先保留示例的外层布局、样式和面板上的 id="router-modal-surface",只替换内部文字、表单和按钮。Android 弹窗需要透明页面背景、自定义导航栏,以及有明确高度的滚动区域;保留示例结构更容易正确接入。

弹窗需要在启动导航后打开。弹窗内可以继续打开弹窗;要打开普通页面,先关闭弹窗。也可用 navigateBack({}) 关闭顶层弹窗,此时不要传入动画时长。

切换浅色与深色

自己的项目直接调用插件接口:

import { setNativeRouterTheme } from '@/uni_modules/kongbai-native-route'

function changeTheme(mode : string) {
  setNativeRouterTheme(mode, (raw : string) => {
    const result = JSON.parse<UTSJSONObject>(raw)
    if (result?.getBoolean('ok') != true) {
      uni.showToast({ title: '主题切换失败,请重试', icon: 'none' })
      return
    }
    // 在这里同步自己的业务页面颜色。
  })
}

按钮调用 changeTheme('dark') 切换深色,调用 changeTheme('light') 切换浅色。此接口负责导航栏与弹窗相关外观,不会自动修改业务页面中写死的文字、背景或组件颜色。

如果复用了上面的示例弹窗及 common 文件,请使用示例提供的 setAppTheme('dark') / setAppTheme('light'),它从 @/common/theme.uts 导入,可以同步示例页面的主题状态。

日常导航应该用哪个接口?

想完成的操作 使用的接口
启动 App 后自动打开第一个业务页面 首个页面就绪后调用一次 startNativeRouter(url, callback)
打开下一个业务页面 navigateTo({ url })
返回上一个业务页面 navigateBack({})
打开一层弹窗 presentNativePage(url, style, callback)
关闭最上层弹窗 dismissNativePage(callback)
主动结束整个导航流程 closeNativeRouter(callback),按业务需要使用

日常操作是打开业务页面、返回上一页,用户无需回到启动页。 首页是本次导航的第一个业务页面,已经没有可返回的上一页。

closeNativeRouter 会关闭整次导航及弹窗,回到最初启动页。只有业务明确需要结束整个流程时才调用,并自行安排关闭后的页面;它不用于普通页面返回,也不表示重新打开首页。上面的自动启动代码仅在首次就绪时执行,不会在关闭导航后自动重新启动。

判断操作是否成功

navigateTo 和 navigateBack 支持 success、fail、complete 三个回调。其他常用接口通过最后一个回调参数返回结果。

回调拿到的是 JSON 字符串,先使用 JSON.parse<UTSJSONObject>(raw) 解析:ok 为 true 表示成功,message 可用于查看失败原因。不要把回调参数直接当作对象读取。

需要观察导航变化时,可使用 setNativeRouterListener(callback) 监听,或使用 inspectNativeRouter(callback) 主动查询状态;它们均从插件导入,结果同样按 JSON 字符串解析。


常见问题

问题 检查方式
插件导入后,页面还是打不开? 检查 vite.config.js,Android 再检查 main.uts;确认已重新编译原生插件或重做自定义基座。
提示目标页面不正确? 页面必须在 pages.json 注册;调用地址以 / 开头、不带 .uvue,也不能是应用入口页。
应用启动后没有自动进入首页? 检查首个页面的 onReady 是否调用了 startNativeRouter;不要在页面尚未就绪的 App.uvue 的 onLaunch 中调用。
提示原生导航已经开启? 启动方法只调用一次,不要在每次 onShow 时重复启动;进入业务页面后使用插件的 navigateTo。
提示上一轮切换尚未结束? 等当前动画完成后再操作,可按快速接入示例在调用期间禁用按钮。
弹窗找不到页面或缺少文件? 注册弹窗页面,并复制它引用的公共文件;插件导入和示例页面复制是两件事。
Android 长页面无法滚动? 使用有明确高度的 scroll-view,设置 :scroll-y="true",可参考示例页面布局。
深色模式没有改变业务页面颜色? 插件不自动修改业务样式,请同步自己的主题状态;示例页面使用 setAppTheme。
更新插件后仍出现旧效果? 停止当前运行任务后重新编译;使用自定义基座时重新制作基座。

使用前请了解

  • 同一导航流程请统一使用本插件的导航方式,避免与其他页面导航方式混用;当前切换完成后再进行下一次操作。
  • 弹窗打开期间,可以继续打开弹窗;如需进入普通页面,请先关闭弹窗。
  • 每次返回一层,暂不支持一次跨越多层返回。
  • 暂不支持 tabBar 页面、EventChannel 和复杂自定义标题栏配置。
  • 视频、相机等特殊页面的转场兼容性尚未验证,使用前请单独测试。

uni-app x 原生路由 · 1.0.0

观看 iOS 真机演示 ↗ · 观看 Android 真机演示 ↗

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

不采集数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。