Skip to content

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
  }
}
  • parseQuery - Convert query string to object
  • LocationQuery - Query parameters type
  • Router Navigation - Programmatic navigation with query parameters

💡 Pro Tip: Use stringifyQuery when 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.

🚀 Vue Router - 让前端路由变得简单而强大 | 构建现代化单页应用的最佳选择