Skip to content

Passing Props to Route Components ​

Using $route or useRoute() in your component creates a tight coupling with the route which limits the flexibility of the component as it can only be used on certain URLs. While this is not necessarily a bad thing, we can decouple this behavior with a props option.

Let's return to our earlier example:

User.vue
vue
<template>
  <div>User {{ $route.params.id }}</div>
</template>

with:

js
import User from './User.vue'

// these are passed to `createRouter`
const routes = [{ path: '/users/:id', component: User }]

We can remove the direct dependency on $route in User.vue by declaring a prop instead:

vue
<!-- User.vue -->
<script setup>
defineProps({
  id: String,
})
</script>

<template>
  <div>User {{ id }}</div>
</template>
vue
<!-- User.vue -->
<script>
export default {
  props: {
    id: String,
  },
}
</script>

<template>
  <div>User {{ id }}</div>
</template>

We can then configure the route to pass the id param as a prop by setting props: true:

js
const routes = [{ path: '/user/:id', component: User, props: true }]

This allows you to use the component anywhere, which makes the component easier to reuse and test.

Boolean mode ​

When props is set to true, the route.params will be set as the component props.

Named views ​

For routes with named views, you have to define the props option for each named view:

js
const routes = [
  {
    path: '/user/:id',
    components: { default: User, sidebar: Sidebar },
    props: { default: true, sidebar: false },
  },
]

Object mode ​

When props is an object, this will be set as the component props as-is. Useful for when the props are static.

js
const routes = [
  {
    path: '/promotion/from-newsletter',
    component: Promotion,
    props: { newsletterPopup: false },
  },
]

Function mode ​

You can create a function that returns props. This allows you to cast parameters into other types, combine static values with route-based values, etc.

js
const routes = [
  {
    path: '/search',
    component: SearchUser,
    props: route => ({ query: route.query.q }),
  },
]

The URL /search?q=vue would pass {query: 'vue'} as props to the SearchUser component.

Try to keep the props function stateless, as it's only evaluated on route changes. Use a wrapper component if you need state to define the props, that way Vue can react to state changes.

Via RouterView ​

You can also pass any props via the <RouterView> slot:

template
<RouterView v-slot="{ Component }">
  <component
    :is="Component"
    view-prop="value"
   />
</RouterView>

WARNING

In this case, all view components will receive view-prop. This is usually not a good idea as it means that all of the view components have declared a view-prop prop, which is not necessarily true. If possible, use any of the options above.

Released under the MIT License.