RouteLocation
Route location type, describing the target of navigation. It is the core type of navigation methods like router.push() / router.replace() / router.relaunch() and the to prop of the RouterLink component.
Input Type: RouteLocationRaw
Navigation methods accept RouteLocationRaw, which supports string paths, path objects, or named objects:
type RouteLocationRaw =
| string
| RouteLocationPathRaw
| RouteLocationNamedRawSupports multiple forms:
// 1. String path
router.push('/pages/about/about')
// 2. Path object
router.push({ path: 'pages/about/about' })
// 3. Named route
router.push({ name: 'about' })
// 4. With parameters
router.push({ path: 'pages/detail/detail', query: { id: '1' } })
router.push({ name: 'detail', params: { info: { id: 1 } } })String Path
The simplest form, directly passing a path string:
// Basic path
router.push('/pages/about/about')
// With query (auto-parsed)
router.push('/pages/detail/detail?id=1&name=Tom')
// Named route name (not recommended, use name form instead)
router.push('about')String path limitations
- Path should start with
/(auto-completed) - Cannot pass
params(only query strings) - Cannot specify advanced options like
animation/events - Recommend using object form for full capabilities
RouteLocationPathRaw
Specify the target path via path:
interface RouteLocationPathRaw {
path: RoutePath
query?: Record<string, QueryValue>
params?: ParamsInput // (requires ParamsPlugin)
persistent?: boolean // (requires ParamsPlugin)
animation?: NavigationAnimation // (requires AnimationPlugin)
events?: EventListeners // (requires ChannelPlugin, push only)
}await router.push({
path: 'pages/detail/detail',
query: { id: '1', tab: 'info' },
animation: { type: 'slide-in-right' },
events: {
onSelectAddress(data) {
console.log('Address selected:', data)
}
}
})RouteLocationNamedRaw
Specify a named route via name:
interface RouteLocationNamedRaw {
name: RouteName
query?: Record<string, QueryValue>
params?: ParamsInput // (requires ParamsPlugin)
persistent?: boolean // (requires ParamsPlugin)
animation?: NavigationAnimation // (requires AnimationPlugin)
events?: EventListeners // (requires ChannelPlugin, push only)
}await router.push({
name: 'detail',
query: { id: '1' },
params: { info: { id: 1, name: 'Tom' } }
})Recommend using named routes
- Decoupling: Path changes don't affect calling code
- Type safety: With the
dtsfeature of@meng-xi/vite-plugin, route names have type hints - Readability:
{ name: 'detail' }is clearer than'/pages/detail/detail'
Property Details
Plugin dependencies
The params, persistent, animation, and events field types are always available (providing complete type hints), but at runtime they require the corresponding plugin to be registered to take effect. Using them without registering the plugin will throw a PLUGIN_REQUIRED error. See Plugin System for details.
path / name
Choose one to specify the target route. name takes priority over path.
query
- Type:
Record<string, QueryValue> - Description: URL query parameters, serialized to strings and appended to the URL
query serialization limitations
Values in query are serialized to strings via encodeURIComponent:
- Simple types (string / number / boolean) pass through normally
- Complex objects are serialized to
[object Object], cannot be restored - Arrays are serialized to comma-separated strings
Use params to pass complex objects.
// ✅ Simple types
router.push({ name: 'detail', query: { id: 123, tab: 'info' } })
// URL: /pages/detail/detail?id=123&tab=info
// ❌ Complex object (cannot be restored)
router.push({ name: 'detail', query: { user: { name: 'Tom' } } })
// URL: /pages/detail/detail?user=%5Bobject%20Object%5D
// Receiver: route.value.query.user === '[object Object]'
// ✅ Array (serialized to string)
router.push({ name: 'detail', query: { ids: [1, 2, 3] } })
// URL: /pages/detail/detail?ids=1%2C2%2C3
// Receiver: route.value.query.ids === '1,2,3' (string)params
- Type:
ParamsInput - Description: Page parameters, supports any serializable data (objects, arrays, nested structures)
- Storage:
- Default in-memory (
persistent: false) - When
persistent: trueis enabled, persisted viauni.setStorageSync
- Default in-memory (
// Pass complex object
await router.push({
name: 'detail',
params: {
user: { name: 'Tom', age: 20 },
tags: ['a', 'b', 'c'],
meta: { source: 'home', timestamp: Date.now() }
}
})
// Receiver
const route = useRoute()
const user = route.value.params.user // { name: 'Tom', age: 20 }
const tags = route.value.params.tags // ['a', 'b', 'c']params vs query
| Feature | query | params |
|---|---|---|
| Type restriction | Simple types only | Any serializable data |
| URL visible | Yes | No |
| H5 refresh preserved | Yes | Only with persistent: true |
| Size limit | URL length limit | storage capacity |
| Use cases | Simple params, shareable | Complex data, page communication |
animation
- Type:
NavigationAnimation - Description: Animation config for this navigation, overrides
meta.animation. Native window animation on App, CSS transition on H5 (onlypush/back)
await router.push({
name: 'detail',
animation: { type: 'slide-in-bottom', duration: 500 }
})events
- Type:
EventListeners - Description: EventChannel event listeners, for target page to source page communication (push only)
// Source page
await router.push({
name: 'select-address',
events: {
onAddressSelected(address) {
console.log('Received address:', address)
// Update page data
form.value.address = address
}
}
})
// Target page
const eventChannel = getCurrentInstance()?.proxy?.getOpenerEventChannel?.()
eventChannel?.emit('onAddressSelected', { city: 'Beijing', detail: 'Chaoyang' })EventChannel advantages
- Cross-page communication without global state or event bus
- Auto cleanup: events auto-invalidate when source page closes
- Type safety: can define event types with TS
persistent
- Type:
boolean - Description: Whether to persist params, overrides global
paramsPersistentconfig
// Global paramsPersistent: false, persist per navigation
await router.push({
name: 'detail',
params: { id: 123 },
persistent: true // Persist this time
})
// Global paramsPersistent: true, don't persist per navigation
await router.push({
name: 'detail',
params: { id: 123 },
persistent: false // Don't persist this time
})Resolved Type: RouteLocation
After navigation completes, useRoute() returns the resolved RouteLocation object:
interface RouteLocation {
path: string
name?: string
meta: RouteMeta
query: Record<string, string>
params: Readonly<ParamObject>
fullPath: string
_synced?: boolean
queryInt(key: string, defaultValue?: number): number | undefined
queryNumber(key: string, defaultValue?: number): number | undefined
queryBool(key: string, defaultValue?: boolean): boolean | undefined
}Special Fields
fullPath
Full path, including query:
const route = useRoute()
console.log(route.value.fullPath)
// /pages/detail/detail?id=1&tab=info_synced
Marks whether this route change is a "state sync" (not a complete navigation):
router.onRouteChange((to, from) => {
if (to._synced) {
// State sync: e.g., physical back button, TabBar click
console.log('State sync, not active navigation')
} else {
// Complete navigation: push / replace / back, etc.
console.log('Complete navigation')
}
})_synced applications
- When physical back button is triggered, route state syncs but
_syncedistrue - When TabBar click switches,
_syncedis alsotrue - Can be used to distinguish active navigation from passive state changes, deciding whether to perform certain side effects
Type Parsing Methods
RouteLocation provides three type-parsing methods — queryInt / queryNumber / queryBool — to get typed data from query.
queryInt
Parse a query parameter as an integer:
const route = useRoute()
const id = route.value.queryInt('id') // 123
const invalid = route.value.queryInt('name') // undefined (when parse fails or no default)
const page = route.value.queryInt('page', 1) // With default, returns 1 when parse failsqueryNumber
Parse a query parameter as a number (supports floats):
const route = useRoute()
const price = route.value.queryNumber('price') // 99.99queryBool
Parse a query parameter as a boolean:
const route = useRoute()
// Only recognizes strings 'true' / '1' → true, 'false' / '0' → false
// Other values (including number 1 / 0, boolean true / false) return defaultValue
const enabled = route.value.queryBool('enabled') // true
const debug = route.value.queryBool('debug') // false
const unknown = route.value.queryBool('other', false) // false (returns default when unrecognized)Practical Example
<script setup lang="ts">
import { useRoute } from '@meng-xi/uni-router'
const route = useRoute()
// Parse multiple types from query
const id = route.value.queryInt('id') // Integer ID
const price = route.value.queryNumber('price') // Float price
const enabled = route.value.queryBool('enabled') // Boolean switch
// Safe access (with defaults)
const page = route.value.queryInt('page', 1)
const size = route.value.queryInt('size', 20)
</script>Related Types
NavigationResult
The return type of push(), extends RouteLocation with an additional eventChannel for page communication:
interface NavigationResult extends RouteLocation {
eventChannel?: EventChannel
}- eventChannel: Page communication event channel. Available by default in
pushmode;replace/relaunchreturnundefinedfor this field by default. WithuseUniEventChannel: trueenabled, all navigation methods return an availableeventChannel.
INFO
NavigationResult extends RouteLocation, so existing code like const route = await router.push(...) works without modification.
EventChannel
Page communication event channel, corresponding to uni-app's native uni.navigateTo EventChannel mechanism:
interface EventChannel {
emit(event: string, ...args: any[]): EventChannel
on(event: string, callback: (...args: any[]) => void): EventChannel
once(event: string, callback: (...args: any[]) => void): EventChannel
off(event: string, callback?: (...args: any[]) => void): EventChannel
}- emit: Send an event to the peer page
- on: Listen for an event from the peer page
- once: Listen for an event from the peer page (fires only once)
- off: Unlisten an event
TIP
All methods return the EventChannel instance, supporting method chaining.
Complete Examples
Basic Navigation
// String path
await router.push('/pages/about/about')
// Named route
await router.push({ name: 'about' })
// With parameters
await router.push({ name: 'detail', query: { id: '1' } })Complex Data Passing
// Pass complex object
await router.push({
name: 'detail',
params: {
user: { name: 'Tom', age: 20 },
items: [
{ id: 1, name: 'Product A', price: 99.9 },
{ id: 2, name: 'Product B', price: 199.9 }
]
},
persistent: true // Persist, still readable after H5 refresh
})Cross-Page Communication
// Source page: open selector and listen for result
await router.push({
name: 'select-address',
events: {
onSelected(address) {
form.value.address = address
},
onCancel() {
console.log('User cancelled selection')
}
}
})
// Target page: send result
const instance = getCurrentInstance()
const channel = instance?.proxy?.getOpenerEventChannel?.()
function selectAddress(address) {
channel?.emit('onSelected', address)
router.back()
}
function cancel() {
channel?.emit('onCancel')
router.back()
}Custom Animation
// Slide in from bottom (common for detail pages)
await router.push({
name: 'detail',
animation: { type: 'slide-in-bottom', duration: 300 }
})
// Fade in (for modal-style pages)
await router.push({
name: 'modal',
animation: { type: 'fade-in', duration: 200 }
})
// Reverse animation on back (animation passed as the second argument)
await router.back(1, {
animation: { type: 'slide-out-bottom', duration: 300 }
})Navigation Mode Control
The navigation mode is determined by the called method: router.replace() replaces the current page, router.relaunch() clears the page stack. To specify the mode when redirecting in guards, use controllable redirect:
// Replace login page after successful login (avoid going back to login)
await router.replace({ name: 'home' })
// Restart app after logout (clear page stack)
await router.relaunch({ name: 'login' })
// Specify mode when redirecting in guards (controllable redirect)
router.beforeEach((to, from) => {
if (to.meta.requireAuth && !isLoggedIn()) {
// Use replace to go to login, avoiding leaving login in the page stack
return { location: { name: 'login', query: { redirect: to.fullPath } }, mode: 'replace' }
}
})Navigation mode is not part of RouteLocationRaw
RouteLocationRaw does not include mode / hash fields. To force replace or clear the stack, call router.replace() / router.relaunch(); to specify the mode when redirecting in guards, use controllable redirect ({ location, mode }). See Route Guards - Controllable Redirect.
Next Steps
- useRoute() — Get route info in components
- Router Instance — Navigation methods in detail
- RouterLink Component — Declarative navigation
