$ npm install uni-router-next
$ npm install --dev uni-router-next-vite-plugin rollup-plugin-node-resolve
传递一个 paegs 数组会与通过 vite 插件读取 pages.json 的 pages 合并
// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import resolve from 'rollup-plugin-node-resolve'
import { UniRouterNextPlugin } from 'uni-router-next-vite-plugin'
export default defineConfig({
plugins: [uni(), UniRouterNextPlugin()],
build: {
rollupOptions: {
plugins: [resolve()],
},
},
})
// router.ts
import { Router } from 'uni-router-next'
export const router = Router.createRouter({
pages: [
{
path: 'pages/index/home',
meta: {},
},
],
})
// main.ts
import { createSSRApp } from 'vue'
import App from './App.vue'
import { router } from './router'
export function createApp() {
const app = createSSRApp(App)
app.use(router)
return {
app,
}
}
import { useRouter } from 'uni-router-next'
const router = useRouter()
router.navigate({
path: '/pages/index/pageB',
type: 'navigateTo'
})
router.navigateTo({
path: '/pages/index/pageB',
})
router.navigateTo...
router.reLaunch...
router.redirectTo...
router.switchTab..
params 将拼接在 url 后,仅支持简单类型,data 可以传递任意类型、任意大小的数据,但在 h5 端刷新后会丢失。
import { useRouter } from 'uni-router-next'
const router = useRouter()
function toB() {
router.navigateTo({
path: '/pages/index/pageB',
params: {
a: 1,
},
data: {
b: 2,
},
})
}
路由跳转会返回一个 Promise,可以拿到跳转页面返回时需要的数据
// A页面
import { useRouter } from 'uni-router-next'
const router = useRouter()
async function toB() {
const res = await router.navigateTo({
path: '/pages/index/pageB',
params: {
a: 1,
},
data: {
b: 2,
},
})
console.log(res) // 输出abc
}
// B页面
import { useRouter } from 'uni-router-next'
const router = useRouter()
router.setBackResult('abc') // 直接设置数据,点击系统自带返回时依然有效
function back() {
router.back('abc')
}
import { useRoute } from 'uni-router-next'
import { onLoad } from '@dcloudio/uni-app'
const route = useRoute()
onLoad(() => {
console.log(route.value)
// data: {}
// fullPath: '/pages/index/home'
// isNavigateComplete: true
// isTab: true
// meta: {}
// params: {}
// path: '/pages/index/home'
})
App.vue 里添加 template,vite 编译时插件会将每个页面 template 替换
<!-- App.vue -->
<template>
<view>xxx</view>
<page-slot></page-slot>
<view>sss</view>
</template>
<!-- pageA.vue 代码 -->
<template>
<view>pageA</view>
</template>
<!-- pageA.vue 经插件处理后 -->
<template>
<view>xxx</view>
<view>pageA</view>
<view>sss</view>
</template>
注册全局组件使用组件
// main.ts
app.component('CustomComp', CustomComp)
<!-- App.vue -->
<template>
<CustomComp ref="CustomCompRef"></CustomComp>
<page-slot></page-slot>
<view>sss</view>
</template>
<!-- pageA.vue 代码 -->
<template>
<view>pageA</view>
</template>
<!-- pageA.vue 经插件处理后 -->
<template>
<CustomComp ref="CustomCompRef"></CustomComp>
<view>pageA</view>
<view>sss</view>
</template>
<script setup>
// ref调用组件
const CustomCompRef = ref()
</script>
包裹, 在组件里注入全局组件方法,在页面里通过 inject 调用全局自定义组件
<!-- AppProvider.vue -->
<template>
<view>
<slot></slot>
<AppSafeArea />
</view>
</template>
<script setup lang="ts">
import { useRoute } from 'uni-router-next'
import AppSafeArea from '../AppSafeArea/AppSafeArea.vue'
const route = useRoute()
</script>
<!-- App.vue -->
<template>
<AppProvider>
<page-slot></page-slot>
</AppProvider>
</template>
- 因为 uni-app 无法阻止页面渲染,通过 isNavigateComplete 标识路由是否完成,可在页面中通过 v-if=“route.isNavigateComplete”渲染元素
- 提供 UniRouterNextProvider 组件
<!-- UniRouterNextProvider.vue -->
<template>
<template v-if="route.isNavigateComplete">
<slot></slot>
</template>
</template>
<script setup lang="ts">
import { useRoute } from 'uni-router-next'
const route = useRoute()
</script>
<!-- App.vue -->
<template>
<UniRouterNextProvider>
<page-slot></page-slot>
</UniRouterNextProvider>
</template>
- 当 isNavigateComplete 为 false 时页面内 vue 除 setup 以外的生命周期和 uni-app 的生命周期都不会执行
- 所有页面内 vue 除 setup 以外的生命周期和 uni-app 的生命周期会等待 app onLaunch 钩子同步执行
- 通过 beforeEach, afterEach 注册全局钩子,通过 api 跳转会在跳转前执行 beforeEach,跳转后执行 afterEach
- 未通过 api 跳转,如 tabbar 切换,系统自带返回则会在跳转页面后执行 beforeEach, aftereach,同时标识 isNavigateComplete, 跳转未成功会阻止页面钩子执行
- beforeEach 在返回 false,抛出错误,返回 Promise.reject,调用 next(false)时会停止,返回其它或者调用 next()则执行下一个守卫,next({path: 'xxx'})后终止当前并执行跳转
- next 须通过 await 调用
// router.ts
export const router = Router.createRouter()
router.beforeEach(async (ctx, next) => {
console.log(ctx)
// {
// from: 离开路由
// isApiCall 是否主动调用api跳转
// isPedding 跳转进行中
// to 目标路由
// type 跳转类型
// }
if (ctx.to?.meta?.auth) {
await next({ path: '/pages/index/pageB' })
}
})
router.beforeEach(async (ctx, next) => {
console.log('beforeEach2')
})
router.afterEach(async (ctx) => {
console.log('afterEach1')
})
仅测试微信小程序和 H5