Skip to content

useRoute()

Get a reactive reference to the current route location. Must be called inside a Vue component's setup() function.

Type

ts
function useRoute(): Ref<RouteLocation>

Return Value

Returns a reactive reference (Ref<RouteLocation>) to the current RouteLocation.

  • Access route info via route.value in <script setup>
  • Auto-unwrapped in templates, use route.path directly
  • Automatically updates when the route changes, triggering component re-render

Reactivity principle

useRoute() returns a reactive reference that automatically updates when the route changes. The same router instance shares the same reactive ref, ensuring all components get consistent route state.

Underlying implementation: the router maintains a ref<RouteLocation> internally, updates it on every navigation completion or state sync, and all useRoute() calls return the same ref.

Call Constraints

Must be called inside setup

useRoute() relies on Vue's inject, so it can only be called inside a component's setup() function (or <script setup>). Calling it in the following scenarios will throw SETUP_ERROR:

  • Regular functions / utility methods
  • Module top level
  • Async callbacks (setTimeout, Promise.then, etc.)

Thrown Errors

Error CodeCondition
SETUP_ERRORCalled outside setup
SETUP_ERRORRouter not installed via app.use(router)

Examples

Basic Usage

vue
<script setup lang="ts">
import { useRoute } from '@meng-xi/uni-router'

const route = useRoute()

// Access via .value in <script setup>
console.log(route.value.path)
console.log(route.value.query.id)
console.log(route.value.params.info)
console.log(route.value.meta.title)
</script>
vue
<template>
  <!-- Auto-unwrapped in template, no .value needed -->
  <view>Current path: {{ route.path }}</view>
  <view>Query: {{ route.query.id }}</view>
  <view>Page params: {{ route.params.id }}</view>
  <view>Page title: {{ route.meta.title }}</view>
</template>

Reading Query Parameters (Type Parsing)

RouteLocation provides three type-parsing methods to avoid manual conversion:

vue
<script setup lang="ts">
import { useRoute } from '@meng-xi/uni-router'

const route = useRoute()

// Assume URL: /pages/detail/detail?id=123&price=19.99&enabled=true

// queryInt - parse as integer
const id = route.value.queryInt('id')        // 123
const page = route.value.queryInt('page', 1) // 1 (default value)

// queryNumber - parse as number (supports floats)
const price = route.value.queryNumber('price')     // 19.99
const total = route.value.queryNumber('total', 0)  // 0 (default value)

// queryBool - parse as boolean
const enabled = route.value.queryBool('enabled')         // true
const visible = route.value.queryBool('visible', false)  // false (default value)
</script>

Type parsing rules

  • queryInt() / queryNumber(): Returns defaultValue on parse failure, or undefined if not provided
  • queryBool(): Only recognizes 'true' / '1'true, 'false' / '0'false; other values return defaultValue

Reading Page Parameters (params)

params is used to pass complex data without exposing it in the URL:

vue
<script setup lang="ts">
import { useRoute } from '@meng-xi/uni-router'

const route = useRoute()

// Assume navigation: router.push({ path: '/detail', params: { id: 123, info: { name: 'Tom' } } })
console.log(route.value.params.id)        // 123
console.log(route.value.params.info)      // { name: 'Tom' }
console.log(route.value.params.info.name) // 'Tom'
</script>

params limitations

  1. Does not support functions, Symbols, or other non-JSON-serializable values
  2. TabBar pages: Since switchTab doesn't support query, __params_key cannot be passed; TabBar pages cannot receive params
  3. Page stack sync: After back(), the target page's params are read via peek (to avoid accidental deletion)
  4. Not persisted by default: Lost on H5 refresh; configure persistent: true to persist

Watching Route Changes

vue
<script setup lang="ts">
import { watch } from 'vue'
import { useRoute } from '@meng-xi/uni-router'

const route = useRoute()

// Watch path changes
watch(
  () => route.value.path,
  (newPath, oldPath) => {
    console.log('Path changed:', oldPath, '→', newPath)
  }
)

// Watch query parameters
watch(
  () => route.value.query.id,
  (newId) => {
    if (newId) fetchDetail(newId)
  }
)
</script>

Sync State with onShow

Physical back button and browser back bypass the router, so route is not automatically updated. Call syncRoute() in onShow:

vue
<script setup lang="ts">
import { onShow } from '@dcloudio/uni-app'
import { useRouter, useRoute } from '@meng-xi/uni-router'

const router = useRouter()
const route = useRoute()

onShow(() => {
  // route will auto-update after sync
  router.syncRoute()
  console.log('Current page:', route.value.path)
})
</script>

Reading Route in Non-Component Code

In non-component scenarios like Pinia stores or utility functions, use the router instance's currentRoute directly:

ts
// src/store/user.ts
import { defineStore } from 'pinia'
import router from '@/router'

export const useUserStore = defineStore('user', () => {
  function getCurrentPath() {
    // ✅ Read currentRoute directly
    return router.currentRoute.path
  }

  function getCurrentQuery() {
    return router.currentRoute.query
  }

  return { getCurrentPath, getCurrentQuery }
})

currentRoute is not reactive

In non-component scenarios, router.currentRoute is not reactive; you get the current snapshot value. For reactive updates, use useRoute() inside components.

Differences from vue-router

Featurevue-routerUni Router
Return typeRouteLocationNormalizedRef<RouteLocation>
Reactive
paramsURL path params (e.g., /user/:id)In-memory params (not exposed in URL)
Type parsing methodsqueryInt() / queryNumber() / queryBool()
Physical back syncAutomaticRequires manual syncRoute()

Next Steps

Released under the MIT License.