stringifyQuery Function | Vue Router
stringifyQuery is a utility function that converts a LocationQuery object into a URL query string. It provides consistent serialization that matches Vue Router's query handling. 🔗
📋 Function Signature
typescript
function stringifyQuery(query: LocationQuery): string🎯 Purpose and Usage
The stringifyQuery function serializes query parameter objects into URL-compatible query strings. It's the inverse operation of parseQuery and ensures consistent query string generation.
Key Features:
- ✅ Query Object Serialization - Converts {key: "value"} to "?key=value"
- ✅ Array Support - Handles array parameters correctly
- ✅ URL Encoding - Properly encodes special characters
- ✅ Consistent Behavior - Matches Vue Router's query string generation
🔍 Parameters
query
- Type:
LocationQuery - Description: The query object to serialize
The function accepts LocationQuery objects with:
- Single values:
{ key: "value" } - Array values:
{ key: ["value1", "value2"] } - Mixed types:
{ single: "value", multiple: ["v1", "v2"] }
💡 Practical Usage Examples
Basic Query Stringification
typescript
import { stringifyQuery } from 'vue-router'
// Simple query object
const query1 = stringifyQuery({ name: 'john', age: '30' })
// Result: "?name=john&age=30"
// Query with array parameters
const query2 = stringifyQuery({ tags: ['vue', 'router', 'composition'] })
// Result: "?tags=vue&tags=router&tags=composition"
// Empty query object
const query3 = stringifyQuery({})
// Result: ""Advanced Query Handling
typescript
// Create search URL with query parameters
function createSearchURL(baseURL: string, filters: SearchFilters): string {
const query = {
q: filters.query,
category: filters.category,
page: filters.page.toString(),
sort: filters.sort
}
const queryString = stringifyQuery(query)
return baseURL + queryString
}
// Update current URL with new query parameters
function updateURLQuery(newParams: Record<string, string>) {
const currentQuery = parseQuery(window.location.search)
const updatedQuery = { ...currentQuery, ...newParams }
const queryString = stringifyQuery(updatedQuery)
window.history.replaceState({}, '', window.location.pathname + queryString)
}Real-World Integration
typescript
class QueryManager {
// Generate shareable URL with current filters
generateShareableURL(filters: SearchFilters): string {
const baseURL = window.location.origin + window.location.pathname
const query = this.filtersToQuery(filters)
const queryString = stringifyQuery(query)
return baseURL + queryString
}
// Sync query parameters with state
syncQueryWithState(state: AppState): void {
const query = {
search: state.searchQuery,
category: state.selectedCategory,
page: state.currentPage.toString(),
sort: state.sortOrder
}
const queryString = stringifyQuery(query)
// Update browser URL without navigation
window.history.replaceState({}, '', window.location.pathname + queryString)
}
private filtersToQuery(filters: SearchFilters): LocationQuery {
const query: LocationQuery = {}
if (filters.query) query.q = filters.query
if (filters.category && filters.category !== 'all') query.category = filters.category
if (filters.page > 1) query.page = filters.page.toString()
if (filters.sort !== 'relevance') query.sort = filters.sort
// Handle array parameters
if (filters.tags.length > 0) query.tags = filters.tags
return query
}
}🔧 Advanced Patterns
Query Optimization
typescript
class QueryOptimizer {
// Remove default values from query
static optimizeQuery(query: LocationQuery, defaults: LocationQuery): LocationQuery {
const optimized: LocationQuery = {}
for (const [key, value] of Object.entries(query)) {
const defaultValue = defaults[key]
// Only include if different from default
if (!this.isEqual(value, defaultValue)) {
optimized[key] = value
}
}
return optimized
}
// Sort query parameters for consistent URLs
static sortQuery(query: LocationQuery): LocationQuery {
const sortedEntries = Object.entries(query).sort(([a], [b]) =>
a.localeCompare(b)
)
return Object.fromEntries(sortedEntries)
}
private static isEqual(a: any, b: any): boolean {
if (Array.isArray(a) && Array.isArray(b)) {
return a.length === b.length && a.every((val, index) => val === b[index])
}
return a === b
}
}Query Analytics
typescript
class QueryAnalytics {
// Track query parameter changes
static trackQueryChanges(
oldQuery: LocationQuery,
newQuery: LocationQuery
): void {
const changes = this.getQueryChanges(oldQuery, newQuery)
if (changes.added.length > 0 || changes.removed.length > 0 || changes.modified.length > 0) {
analytics.track('query_parameters_changed', {
added: changes.added,
removed: changes.removed,
modified: changes.modified,
timestamp: Date.now()
})
}
}
private static getQueryChanges(oldQuery: LocationQuery, newQuery: LocationQuery) {
const allKeys = new Set([
...Object.keys(oldQuery),
...Object.keys(newQuery)
])
const changes = {
added: [] as string[],
removed: [] as string[],
modified: [] as string[]
}
for (const key of allKeys) {
const oldValue = oldQuery[key]
const newValue = newQuery[key]
if (oldValue === undefined && newValue !== undefined) {
changes.added.push(key)
} else if (oldValue !== undefined && newValue === undefined) {
changes.removed.push(key)
} else if (!this.isEqual(oldValue, newValue)) {
changes.modified.push(key)
}
}
return changes
}
}🔗 Related APIs
parseQuery- Convert query string to objectLocationQuery- Query parameters type- Router Navigation - Programmatic navigation with query parameters
💡 Pro Tip: Use
stringifyQuerywhen you need to generate query strings that match Vue Router's format. This ensures consistency between your custom query handling and the router's built-in functionality.