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,
:productIdis a dynamic parameter that can take any value.- When a user accesses a route like
/product/123, the value123will 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
}
};