Composables
unix-router provides Vue 3 composables that integrate seamlessly with <script setup> in .uvue files: useRouter / useRoute / useLink / useOpenerEventChannel / onRouteChange, plus in-component guards.
useRouter()
Returns the router instance:
import { useRouter } from '@meng-xi/unix-router'
const router = useRouter()
router.push('/pages/about/about') // navigate
router.back() // go back
router.currentRoute.path // current path (getter, not reactive)Resolution order:
- setup context: goes through
provide/injectfirst (in multi-instance scenarios, picks the router injected into this component tree); - non-setup context (options-style methods, event callbacks): falls back to the global active router (registered via
app.use(router)); - neither available → throws (call
app.use(router)first).
So it works not only in <script setup> but also in options-style methods and event callbacks.
useRoute()
Returns the global reactive object (the current route location). Access fields directly in both script and template (no .value):
import { useRoute } from '@meng-xi/unix-router'
const route = useRoute()
route.path // /pages/about/about
route.fullPath // /pages/about/about?id=1
route.query.get('id') // '1' (Map API)
route.params.get('from') // params (Map API)
route.meta.title // metadata
route.name // named route name; null when unnamedWhen does it update?
- After a forward navigation (
push/replace/relaunch) completes and is recorded (the state write that happens beforeafterEach) - Forward navigations are the only writes.
back()andsyncRoute()update only the router's internalcurrentRoute(router.currentRoute); they never write back to the reactive object returned byuseRoute()— the two states are maintained independently.
Therefore reading a stale value outside of a forward navigation is normal; for page-level data, rely on the page's own
onLoad/onShow.
<template>
<view class="page">
<text>Current: {{ route.path }}</text>
</view>
</template>
<script setup lang="uts">
import { useRoute } from '@meng-xi/unix-router'
const route = useRoute()
</script>useLink()
The machinery behind declarative navigation: returns reactive link state plus a trigger function, ideal for custom link / Tab / menu components.
import { useLink } from '@meng-xi/unix-router'
const link = useLink({ to: '/pages/about/about' })
// full options: { to, replace?: boolean, relaunch?: boolean }
link.route // ComputedRef<RouteLocation> — the resolved target route
link.href // ComputedRef<string> — full path (use link.href.value in script)
link.isActive // ComputedRef<boolean> — active (path prefix match)
link.isExactActive // ComputedRef<boolean> — exactly active (path equality)
await link.navigate() // performs the navigation (relaunch / replace / push, dispatched by options)
isActiveand friends returnComputedRef— you need.valuein script; they auto-unwrap in templates.
useOpenerEventChannel()
On the opened page, returns the directed communication channel with the "opener" (on / once / off / emit). Requires EventsPlugin, and this page must have been opened by a navigation carrying events; otherwise it returns null:
import { useOpenerEventChannel } from '@meng-xi/unix-router'
const channel = useOpenerEventChannel()
if (channel != null) {
channel.emit('done', 'ok') // send data back to the opener
}See Inter-Page Communication for details.
onRouteChange: Listening for Route Changes
router.onRouteChange registers a global listener (fires after any navigation and state sync) and returns a cancel function:
const stop = router.onRouteChange((to, from) => {
console.log(`from ${from.fullPath} to ${to.fullPath}`)
})
// when no longer needed
stop()Route State Sync
The router's internal currentRoute (what router.currentRoute reads and what onRouteChange reports) is aligned with the real page stack via syncRoute():
- H5:
app.use(router)registers a global mixin that automatically callssyncRoute()on every page'sonShow— no manual handling needed. - Native platforms (App / Mini Program): call
router.syncRoute()yourself in the page'sonShowto cover non-router navigation such as the physical back button and TabBar switching.
Note:
useRoute()is a separately maintained reactive object — only forward navigations write it.syncRoute()/back()update the router's internal state only; to read the real page-stack state outside a forward navigation, userouter.currentRouteor the page's ownonLoad(options).
When onShow fires before the sync completes (e.g. you need launch parameters in the first frame), prefer reading the launch query directly in onLoad(options):
onLoad((options) => {
// options holds the native launch parameters, independent of route sync
const id = options?.['id'] ?? ''
})In-Component Guards
| Function | When it fires |
|---|---|
onBeforeRouteLeave | When leaving the current page (most useful) |
onBeforeRouteUpdate | On update (rarely fires under the static page model) |
onBeforeRouteEnter | On enter (limited effect) |
uni-app x creates a new page instance for every navigation (no keep-alive reuse), so
onBeforeRouteEnter/Updateare limited andonBeforeRouteLeaveis the most practical. See Route Guards for details.
Next Steps
- Route Guards — global and in-component guards
- Inter-Page Communication — useOpenerEventChannel and EventsPlugin
- useRoute API | useRouter API
