Navigating Vue Routes With Parameters: Declarative and Programmatic Approaches
Vue provides multiple mechanisms for handling client-side routing and state transitions. Each approach interacts differently with the browser's history stack and parameter serialization strategies.
Declarative Navigation via <router-link>
The component-based approach allows markup-driven routing. Route targets can be defined using string paths or route objects containing name/path configurations.
<!-- Unparameterized navigation -->
<router-link :to="{ name: 'UserProfile', path: '/profile' }">View Profile</router-link>
<!-- Passing parameters via 'params' -->
<router-link :to="{ name: 'UserProfile', params: { userId: 8842 } }">
Open Detail
</router-link>
<!-- Passing parameters via 'query' -->
<router-link :to="{ name: 'UserProfile', query: { section: 'settings', tabId: 3 } }">
Settings
</router-link>
When utilizing params, the destination route must explicitly define the dynamic segment in its configuration (e.g., path: '/profile/:userId'). Without this explicit path mapping, the parameter persists only during the initial navigation and vanishes upon page refresh. Query parameters do not require route definition but will always appear in the browser address bar.
Accessing these values occurs through the $route instance:
const userId = this.$route.params.userId;
const section = this.$route.query.section;
Programmatic Navigation with router.push()
For conditional or event-driven routing, invoke the router instance directly within component methods or lifecycle hooks.
// Navigate without extra data
this.$router.push({ name: 'Dashboard', path: '/dash' });
// Attach query parameters to URL
this.$router.push({
name: 'Analytics',
query: { campaignId: 'x9k2', source: 'newsletter' }
});
// Inject params into route path
this.$router.push({
name: 'Account',
params: { accountId: 'acc_5501' }
});
Like the declarative approach, retrieving pushed parameters relies on $route.params or $route.query. Note that push appends an entry to the browser history, enabling standard back-button functionality.
History Replacement via router.replace()
The replacement method functions identically to push regarding parameter handling, but modifies how the navigation affects the session history.
this.$router.replace({ name: 'AuthLogin', params: { redirectUrl: '/checkout' } });
Executing replace overwrites the current history entry rather than creating a new one. Consequently, pressing the browser's back button skips the replaced screen entirely, moving to the preceding context. This pattern is typically employed for mandatory redirects or authentication gateways.
History Stack Traversal with router.go()
Direct manipulation of the session stack uses integer offsets relative to the current posittion.
// Go back two pages
this.$router.go(-2);
// Advance forward one step
this.$router.go(1);
This mechanism does not accept route objects or payloads. It operates purely on historical distance, making it suitable for custom navigation controls like breadcrumbs or history wheels.
Parameter Serialization: query vs params
Understanding how parameters are encoded determines which strategy suits your application architecture.
| Feature | query |
params |
|---|---|---|
| HTTP Analogy | GET request | POST request |
| URL Visibility | Appended to pathname (e.g., ?key=value) |
Hidden from URL unlesss path is configured |
| Route Definition Required | No | Yes (e.g., path: '/resource/:id') |
| Persistence on Refresh | Always preserved | Retained only if dynamic path exists |
| Typical Use Case | Filtering, pagination, search states | Resource identifiers, authenticated views |
Misconfiguring params without a corresponding path segment results in ephemeral data that resets on reload. Conversely, excessively sensitive data should avoid query due to address bar exposure and browser logging.