主题
编程式导航
在 uni-simple-router
中,你可以使用编程式导航来实现页面的跳转和导航操作。编程式导航通常是通过调用路由实例的方法来实现的。
版本陷阱
导航到新地址
如果您需要进行页面导航,uni-simple-router
提供了相应的API来满足您的需求。您可以调用相应的方法并传递相应的参数来完成导航操作。需要注意的是,在非H5端可能存在一些特定的限制和要求。例如,在导航到 原生Tabbar 页面时,必须使用 pushTab
方法进行导航操作。这些限制是由各个平台的特性所决定的,uni-simple-router
会根据平台的要求进行相应的处理,以确保导航的正确执行。
使用 路由实例 完成导航:
js
import {
createRouter
} from '@/uni-simple-router'
const router = createRouter({
platform:process.env.VUE_APP_PLATFORM as platformRule,
routes:[
// ...
]
})
// 字符串路径
router.push('/users/eduardo')
// 带有路径的对象
router.push({ path: '/users/eduardo' })
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })
// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// 跳转到原生Tabbar
router.pushTab({ name: 'tab1' })
// 关闭所有页面并打开指定页面
router.replaceAll({ name: 'my' })
// 替换当前页面栈并打开新页面
router.replace({ name: 'record' }).then(()=>{
console.log(`导航完成`)
})
// 返回页面
router.back(1)
使用 选项API 完成导航:
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter } from '@/uni-simple-router';
const router = useRouter();
function goNav(name:string){
router.replace({
name
})
}
</script>
使用 uni.$Router 完成导航:
uni-simple-router
在实例化时会将实例挂载到uni.$Router
上,这样你就可以在不方便导入实例的地方轻松访问路由器实例。这对于一些特殊场景,比如在nvue页面中使用路由实例,非常方便。通过uni.$Router
,你可以直接访问路由器的各种方法和属性,以便进行导航、监听路由事件等操作。
ts
// xxx.nvue
<script setup lang="ts">
import { watch } from 'vue'
const router = uni.$Router
const route = uni.$Route
watch(route,(value)=>{
console.log(value)
})
router.push({name: `my`})
console.log(route.value)
</script>
温馨提示
- 在
Vue
实例中,你可以通过$Router
访问路由实例。因此你可以调用this.$Router.push
。 - 在
Vue
实例中,你同样可以通过$Route
访问路由元信息,因此你可以调用this.$Route.query
获取参数。
导航到子路由
假设现在你准备跳转到一个新的子路由页面时,以下是可能发生的情况。
假设我们的路由表关系如下:
js
import {
__dynamicImportComponent__
} from '@/uni-simple-router'
const routes = [
{
path: '/admin',
component: __dynamicImportComponent__(`@/pages/AdminLayout.vue`,{
pageType:`top`,
}),
children: [
{
path: 'dashboard/:id',
name:`dashboard`,
component: __dynamicImportComponent__(`@/pages/DashboardPage.vue`)
},
]
},
{
path: '/notify',
component: __dynamicImportComponent__(`@/pages/NotifyLayout.vue`,{
pageType:`top`,
}),
children: [
{
path: 'type/:id',
name:`notifyType`,
component: __dynamicImportComponent__(`@/pages/NotifyTypePage.vue`)
},
]
}
];
- 假设你当前位置在
/admin
下,准备跳转到name
为dashboard
的子路由页面。在导航发生变化时,页面不会出现切屏动画,而是在当前页面下直接更新视图。这是通过<simple-router-view>
组件挂载DashboardPage.vue
组件实现的。同时,父级组件执行 updated 的生命周期钩子函数,DashboardPage.vue
组件也执行对应的挂载生命周期钩子函数。此外,$Route
对象的路由元信息也会响应式地发生变化。 - 假设你当前位置在
/admin
下,准备跳转到name
为notifyType
的子路由页面。在导航发生变化时,页面将出现切屏动画,并创建一个新的WebView
来渲染NotifyLayout.vue
和NotifyTypePage.vue
组件。同时,$Route
对象的路由元信息也会响应式地发生变化。
综上所述,根据你所在位置的不同,导航行为也会有所不同。如果你所在的位置是根组件(顶级页面)于目标根组件(顶级页面)相同,则会直接在当前页面下更新视图;否则会创建新的 WebView
来渲染页面。
陷阱提示
- 如果你在非 H5端(例如小程序或App端)执行子路由之间的跳转,创建的页面栈不会影响真机物理返回按键的逻辑。这意味着当你在子路由页面中进行跳转时,无论跳转到多少子路由页面,按下真机物理返回按键时,会直接返回到父级页面或根页面,而不会逐级返回到之前的子路由页面。
router.push
push
方法在功能上与 uni.navigateTo 相同,它们实现了完全一致的效果。这个方法会向 history
栈添加一个新的记录,保留当前页面。uni.navigateTo 支持通过 events
参数进行页面间的通信,但在uni-simple-router
中,导航API取消了 events
参数的使用,并采用了另一种组件之间的通信方式。如果你需要详细了解,请参考组件之间的通信方式文档。
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter,parserInstance } from '@/uni-simple-router';
const router = useRouter();
router.push({name:`newPage`})
.then(()=>{
//导航成功,传递通讯数据
parserInstance(`newPage`,[
(instance)=>instance.newPageNotify(`来自星星的它`)
])
})
</script>
router.pushTab
pushTab
方法在功能上与 uni.switchTab 相同,它们实现了完全一致的效果。这个方法会将所有非原生Tabbar
页面都关闭,然后跳转到指定TabBar页面
。如果你需要组件与组件间通讯,请参考组件之间的通信方式文档。
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter,parserInstance } from '@/uni-simple-router';
const router = useRouter();
router.pushTab({name:`newTab`})
.then(()=>{
//导航成功,传递通讯数据
parserInstance(`newTab`,[
(instance)=>instance.newPageNotify(`来自星星的它`)
])
})
</script>
router.replace
replace
方法在功能上与 uni.redirectTo 相同,它们实现了完全一致的效果。这个方法会关闭当前页面,跳转到应用内的某个页面。如果你需要组件与组件间通讯,请参考组件之间的通信方式文档。
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter } from '@/uni-simple-router';
const router = useRouter();
router.replace({name:`otherPage`})
</script>
router.replaceAll
replaceAll
方法在功能上与 uni.reLaunch 相同,它们实现了完全一致的效果。这个方法会关闭所有页面,打开到应用内的某个页面。
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter } from '@/uni-simple-router';
const router = useRouter();
router.replaceAll({name:`home`})
</script>
router.back
back
方法在功能上与 uni.navigateBack 相同,它们实现了完全一致的效果。这个方法会关闭当前页面,返回上一页面或多级页面。如果你需要组件与组件间通讯,请参考组件之间的通信方式文档。
ts
/// xxx.vue
<script setup lang="ts">
import { useRouter } from '@/uni-simple-router';
const router = useRouter();
// 返回一层
router.back(1)
// 返回多层
router.back(2)
// 如果 history 记录不够用,那就默默地失败呗
router.back(100)catch(e=>{
console.log(e)
})
</script>
uni-app原生方法
除了使用uni-simple-router
提供的导航API,如果你仍然喜欢使用uni-app
原生的导航方法,uni-simple-router
也提供了这个功能。它在底层桥接了uni-app
的原生导航方法,因此你可以传递原生导航方法的所有参数,并且可以在使用原生方法时传递与uni-simple-router
导航相同的参数。但是需要注意,使用uni-app
原生方法可能存在一些缺点:
uni-app
原生方法只能用于跳转到顶级页面,无法直接跳转到嵌套子页面中。uni-app
原生方法无法直接跳转动态路由匹配的页面。- 使用复杂的URL字符串传参可能会使代码更加复杂和难以维护。
综上所述,虽然uni-simple-router
提供了对uni-app
原生导航方法的支持,但建议尽量使用uni-simple-router
提供的导航API,以获得更好的路由管理和参数传递的体验。
一个简单的列子:
js
import {
__dynamicImportComponent__
} from '@/uni-simple-router'
const routes = [
{
path: '/admin',
component: __dynamicImportComponent__(`@/pages/AdminLayout.vue`,{
pageType:`top`,
}),
children: [
{
path: 'dashboard/:id',
name:`dashboard`,
component: __dynamicImportComponent__(`@/pages/DashboardPage.vue`)
},
]
}
];
假设现在的路由关系为嵌套路由,我们使用不同的方式跳转,请关注下方的代码:
js
// 原生方法
uni.navigateTo({
url:`/pages/AdminLayout?name=hhyang`
})
// 或者使用如下:
uni.navigateTo({
path:`/admin`,
query:{
name:`hhyang`
}
})
// 假如你正在vue组件内部,你可以直接访问 $Router
this.$Router.push(`/admin?name=hhyang`)
// 跳转到嵌套动态路由
uni.navigateTo({
path:`/admin/dashboard/123`,
})
// 或者
this.$Router.push({
name:`dashboard`,
params:{
id:123
}
})