Кастомная функция stringifyQuery

Vue Router предоставляет гибкий механизм работы с маршрутизацией в приложениях на Vue.js. Одним из таких механизмов является возможность кастомизации сериализации объектов query-параметров через функцию stringifyQuery. Эта функция определяет, как объект query преобразуется в строку URL.

Основы работы

По умолчанию Vue Router использует встроенный метод для сериализации query-параметров. Например, объект:

{
  page: 1,
  filter: 'active'
}

будет автоматически преобразован в строку:

?page=1&filter=active

Однако бывают ситуации, когда стандартная сериализация не подходит: требуется специфический формат, кодировка символов или работа с массивами в особом виде. Для таких случаев используется кастомная функция stringifyQuery.

Определение кастомной функции

Функция stringifyQuery передается при создании маршрутизатора в опциях:

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ],
  stringifyQuery(query) {
    // query — объект с параметрами
    const parts = []
    for (const key in query) {
      const value = query[key]
      if (value == null) continue // игнорируем null или undefined
      if (Array.isArray(value)) {
        value.forEach(v => parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`))
      } else {
        parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
      }
    }
    return parts.length ? `?${parts.join('&')}` : ''
  }
})

В этом примере массивы сериализуются в виде повторяющихся ключей:

{ tags: ['vue', 'router'] } 
// преобразуется в
?tags=vue&tags=router

Обработка специальных символов

stringifyQuery позволяет гибко управлять кодировкой символов. Например, если необходимо сохранить пробелы как + вместо %20, можно изменить обработку значений:

stringifyQuery(query) {
  const parts = []
  for (const key in query) {
    const value = query[key]
    if (value == null) continue
    const encodedKey = encodeURIComponent(key)
    const encodedValue = encodeURIComponent(value).replace(/%20/g, '+')
    parts.push(`${encodedKey}=${encodedValue}`)
  }
  return parts.length ? `?${parts.join('&')}` : ''
}

Теперь объект:

{ search: 'vue router' }

будет сериализован в:

?search=vue+router

Поддержка вложенных объектов

Для сложных query-параметров с вложенными объектами или массивами можно реализовать рекурсивную сериализацию:

function stringifyNestedQuery(query, prefix = '') {
  const parts = []
  for (const key in query) {
    const value = query[key]
    const fullKey = prefix ? `${prefix}[${key}]` : key
    if (value === null || value === undefined) continue
    if (typeof value === 'object' && !Array.isArray(value)) {
      parts.push(stringifyNestedQuery(value, fullKey))
    } else if (Array.isArray(value)) {
      value.forEach(v => parts.push(`${encodeURIComponent(fullKey)}[]=${encodeURIComponent(v)}`))
    } else {
      parts.push(`${encodeURIComponent(fullKey)}=${encodeURIComponent(value)}`)
    }
  }
  return parts.join('&')
}

const router = createRouter({
  history: createWebHistory(),
  routes: [],
  stringifyQuery(query) {
    const result = stringifyNestedQuery(query)
    return result ? `?${result}` : ''
  }
})

Теперь объект:

{
  user: { name: 'Alice', roles: ['admin', 'editor'] },
  page: 2
}

преобразуется в строку URL:

?user[name]=Alice&user[roles][]=admin&user[roles][]=editor&page=2

Взаимодействие с маршрутизатором

Функция stringifyQuery вызывается автоматически при переходах с router.push или при формировании ссылок <router-link>. Например:

router.push({ path: '/search', query: { q: 'vue router' } })

будет использовать кастомную функцию для формирования итогового URL. Это позволяет полностью контролировать вид query-параметров на стороне клиента.

Советы по использованию

  • Игнорирование пустых значений: полезно исключать null и undefined для сокращения длины URL.
  • Согласованная кодировка: всегда использовать encodeURIComponent, чтобы избежать ошибок с нестандартными символами.
  • Поддержка массивов и вложенных объектов: упрощает работу с фильтрами и сложными параметрами запросов.
  • Производительность: если функция выполняет сложные рекурсии, следует учитывать возможные задержки при больших объектах query.

Примеры применения

  1. Массовая фильтрация товаров:
router.push({
  path: '/products',
  query: { category: ['books', 'electronics'], available: true }
})

Используя кастомную функцию, массивы и булевы значения преобразуются в читаемый и предсказуемый формат URL.

  1. Форматирование для внешних API:

Некоторые API требуют query-параметры в специфическом формате, например с использованием + для пробелов или нижнего регистра ключей. stringifyQuery позволяет полностью контролировать этот процесс.

  1. Поддержка истории с вложенными фильтрами:

При реализации сложной панели фильтров с вложенными категориями и тегами можно сериализовать все параметры в одну строку query, сохраняя при этом структуру объекта.


Кастомная функция stringifyQuery — это мощный инструмент для точного контроля формирования URL в Vue Router. Она обеспечивает гибкость при работе с массивами, вложенными объектами и кодировкой, а также позволяет адаптировать маршрутизацию под специфические требования приложений и внешних API.