Dynamic routes are routes that can change based on certain parameters or values.
This allows us to show content by building routes that can adapt to different content or data (like user profiles, product details)
That is, instead of defining a fixed route like /user
, we can define a dynamic route like /user/:id
, where :id
is a parameter that can take any value.
Defining Parameters in Routes
In Vue Router, route parameters are defined using the :
prefix followed by the parameter name. For example:
{ path: '/product/:productId', component: ProductDetails }
Here,
:productId
is a dynamic parameter that can take any value.- When a user accesses a route like
/product/123
, the value123
will be assigned to the parameterproductId
.
Multiple Parameters
It is also possible to define routes with multiple parameters. For example:
{ path: '/category/:categoryId/product/:productId', component: ProductDetail }
In this case, the route /category/5/product/10
will assign 5
to categoryId
and 10
to productId
.
Optional Parameters
Sometimes, it is useful to define parameters that are not mandatory. To do this, we can use the ?
symbol after the parameter name. For example:
{ path: '/user/:userId?', component: UserProfile }
In this case, the route /user
will also be valid, and the parameter userId
will be undefined
.
Nested Routes
Dynamic routes can also be combined with nested routes to create more complex structures. For example:
const routes = [
{
path: '/user/:userId',
component: UserLayout,
children: [
{ path: 'profile', component: UserProfile },
{ path: 'settings', component: UserSettings }
]
}
];
In this case, the routes /user/1/profile
and /user/1/settings
will be available within the UserLayout
layout.
Accessing Parameters in Components
Once we have defined a dynamic route, we need to access the parameters in our component in order to display the corresponding content.
Vue Router provides two main ways to access the parameters, depending on whether we are using the Composition API or the Options API.
In the Composition API, we use the useRoute()
function to access the route parameters:
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
const userId = route.params.userId;
console.log(`User ID: ${userId}`);
// Here we could make an API call to get the user's data
}
};
In the Options API, we can access the route parameters through this.$route.params
. For example:
export default {
name: 'UserProfile',
created() {
const userId = this.$route.params.userId;
console.log(`User ID: ${userId}`);
// Here we could make an API call to get the user's data
}
};
Reactivity of Parameters
Route parameters are reactive. This means that if the value of a parameter changes (for example, when navigating from /user/1
to /user/2
), the component will automatically update.
If you need to perform a specific action when a parameter changes, you can use a watch
on the parameter:
<script setup>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
watch(() => route.params.userId, newUserId => {
console.log(`User ID changed to: ${newUserId}`);
// API call to get the new user's data
});
</script>
Parameter Validation
In some cases, it is useful to validate route parameters to ensure they meet certain criteria before rendering the component.
Vue Router allows defining route validators using the props
property.
For example, suppose we want to ensure that the userId
parameter is a number:
const routes = [
{
path: '/user/:userId',
component: UserProfile,
props: (route) => ({
userId: Number(route.params.userId) || 0
})
}
];
In this example, if the userId
parameter is not a number, the default value 0
will be assigned.
Practical Examples
User Profile
Suppose we are building a social media application. We can define a dynamic route for user profiles:
const routes = [
{ path: '/profile/:username', component: UserProfile }
];
In the UserProfile
component, we access the username
parameter to load the user data:
export default {
setup() {
const route = useRoute();
const username = route.params.username;
// API call to get the user's data
}
};
Product Details
In an online store, we can define a dynamic route for product details:
const routes = [
{ path: '/product/:productId', component: ProductDetail }
];
In the ProductDetail
component, we access the productId
parameter to load the product details:
export default {
setup() {
const route = useRoute();
const productId = route.params.productId;
// API call to get the product details
}
};