логотип PurpleSchool
логотип PurpleSchool

Использование query-параметров и их обработка в маршрутах Vue

Автор

Олег Марков

Введение

В современном веб-разработке параметры запроса (query-параметры) позволяют управлять состоянием и отображением страниц без необходимости обновлять их полностью. Во Vue и его инфраструктуре маршрутизации (чаще всего это vue-router) query-параметры часто применяются для фильтрации, поиска, пагинации, отслеживания пользовательских предпочтений и передачи данных между страницами.

В этой статье вы получите подробное представление о том, как работать с query-параметрами в маршрутах Vue. Здесь мы рассмотрим как читать параметры запроса, обновлять их в реальном времени, реагировать на их изменения, а также организовывать чистый и лаконичный код обработки. Вы увидите практические примеры использования для Vue Router как версии 2, так и версии 3/4, поскольку многие проекты используют разные версии.

Основы работы с query-параметрами во Vue

Что такое query-параметры и зачем они нужны

Query-параметры — это часть URL, следующая за вопросительным знаком (?), где различные аргументы разделяются амперсандом (&). Пример:

/products?category=shoes&page=2

В этом примере:

  • category и page — это названия параметров,
  • shoes и 2 — их значения соответственно.

Query-параметры обычно используются для:

  • передачи дополнительных данных маршрутам (например, фильтры или поисковые запросы),
  • изменения состояния интерфейса без необходимости навигации на новую страницу,
  • синхронизации представления и состояния приложения с URL.

Как параметры запроса интегрированы во Vue Router

vue-router — стандартное решение для маршрутизации во Vue. Все параметры запроса автоматически попадают в объект route, который доступен внутри компонентов. Вам не нужно настраивать обработку этих параметров отдельно: Vue Router сделает это за вас.

Пример маршрута с query-параметрами

Рассмотрим небольшой фрагмент кода для открытия страницы товаров с фильтрацией:

// пример route: /products?category=sneakers&page=3
{
  path: '/products',
  name: 'Products',
  component: ProductsPage
}

В компоненте ProductsPage к параметрам запроса вы получаете доступ через свойство $route.query.

Доступ к query-параметрам внутри компонентов

Давайте посмотрим, как получить значение параметров запроса на практике:

export default {
  name: 'ProductsPage',
  computed: {
    category() {
      // Получаем параметр 'category' из строки запроса
      return this.$route.query.category || 'all';
    },
    page() {
      // Получаем параметр 'page' и конвертируем в число, если не задан — 1
      return parseInt(this.$route.query.page, 10) || 1;
    }
  }
}

В этом примере мы определили вычисляемые свойства, которые возвращают значения соответствующих параметров. Это позволяет удобно использовать их в шаблоне и логике компонента:

<!-- Пример использования в шаблоне -->
<h2>Категория: {{ category }}</h2>
<p>Страница: {{ page }}</p>

Как устанавливать и изменять query-параметры программно

Иногда вам нужно изменить параметры запроса, не обновляя страницу и не теряя текущее состояние. Смотрите, я покажу вам, как это сделать с помощью методов Vue Router.

Использование метода $router.push

methods: {
  goToPage(newPage) {
    this.$router.push({
      path: this.$route.path,
      query: {
        ...this.$route.query,
        page: newPage
      }
    });
  }
}
  • this.$route.path сохраняет текущий путь.
  • ...this.$route.query сохраняет остальные параметры запроса.
  • page: newPage устанавливает новый параметр страницы.

Ценность такого подхода в том, что вы не теряете остальные параметры при смене одного, что часто нужно при реализации фильтров, поиска, сортировки.

Использование метода $router.replace

В ситуациях, когда вы не хотите добавлять новую запись в историю браузера, используйте replace:

this.$router.replace({
  path: this.$route.path,
  query: { ...this.$route.query, sort: 'price' }
});

Это обновит URL и состояние компонента, но пользователь не сможет вернуться к предыдущему состоянию с помощью кнопки "Назад".

Query-параметры и переходы по ссылке

Чтобы сформировать ссылку с параметрами запроса, используйте компонент <router-link>:

<router-link
  :to="{ path: '/products', query: { category: 'boots', page: 1 } }"
>
  Ботинки — страница 1
</router-link>

Это эквивалентно переходу на /products?category=boots&page=1.

Для добавления или изменения только одного параметра, комбинируйте текущие параметры с нужными:

<router-link
  :to="{ path: $route.path, query: { ...$route.query, page: 2 } }"
>
  Следующая страница
</router-link>

Реакция компонента на изменения query-параметров

Часто пользователь может менять параметры через UI (например, вводя значение фильтра или кликая пагинацию), и ваше приложение должно реагировать на эти изменения.

Использование watch для отслеживания параметров

Vue не обновляет компонент при изменении только строки запроса (если путь не изменился). Вам нужно явно следить за изменениями. Сделайте это через watch:

export default {
  watch: {
    // Следить за изменением всего объекта query
    '$route.query': {
      immediate: true, // Вызвать обработчик сразу при монтировании
      handler(newQuery, oldQuery) {
        // Выполните необходимые действия, например загрузку данных
        this.fetchProducts(newQuery);
      }
    }
  },
  methods: {
    fetchProducts(query) {
      // Загрузка товаров с учетом новых фильтров
    }
  }
}

Если нужно реагировать только на определенный параметр:

watch: {
  '$route.query.category'(newCategory, oldCategory) {
    // Логика при изменении категории
  }
}

Учитывайте: переиспользование компонента

Иногда компонент используется для разных путей, и нужно сбрасывать состояние при смене локации (path). Следите не только за query, но и за path при необходимости.

Валидация и дефолтные значения параметров запроса

Query-параметры — это всегда строки, даже если вы ожидаете число, boolean и пр. Важно явно конвертировать и валидировать значения во избежание багов.

Пример конвертации:

computed: {
  page() {
    const page = parseInt(this.$route.query.page, 10);
    // Если NaN или отрицательное число — по умолчанию 1
    return (isNaN(page) || page < 1) ? 1 : page;
  }
}

Часто нужно подставлять значения "по умолчанию", если параметр не задан или невалиден, чтобы не ломать отображение компонента.

Сложные случаи: массивы, вложенные объекты и сериализация

Vue Router по умолчанию преобразует массивы в несколько одноимённых параметров:

/products?color=red&color=blue

Внутри компонента это выглядит так:

this.$route.query.color 
// Если один цвет: 'red', если несколько: ['red', 'blue']

Если вы хотите поддерживать структуру объектов, предложите вашему API или UI работать только с простыми типами и массивами. Используйте методы сериализации (например, JSON.stringify/parse), если все же нужно передавать объекты:

// Добавляем фильтр-объект в запрос
this.$router.push({
  path: '/products',
  query: {
    filter: JSON.stringify({ minPrice: 10, maxPrice: 150 }),
  }
});

Десериализация внутри компонента:

computed: {
  filter() {
    try {
      return JSON.parse(this.$route.query.filter || '{}');
    } catch (e) {
      return {};
    }
  }
}

Сброс query-параметров и очистка фильтров

Когда пользователь хочет сбросить все фильтры, вы можете полностью очистить параметры запроса:

this.$router.push({
  path: this.$route.path,
  query: {} // Очищаем все параметры
});

Для сброса отдельных параметров — просто не включайте их в новый объект query.

Ограничения и подводные камни

Количество и длина параметров

Браузеры и серверы имеют лимиты на длину URL, поэтому старайтесь не передавать слишком много или большие данные через query.

Совместимость с SSR/Nuxt

Если вы используете сервер-сайд-рендеринг или Nuxt, параметры запроса доступны через context.route.query на сервере и клиенте.

SEO и кэширование

Query-параметры часто оцениваются поисковиками как отдельные страницы. Для статических и SEO-критичных проектов минимизируйте разнообразие незначимых query-параметров.

Тестирование и отладка

Работая с query-параметрами, всегда проверяйте:

  • что параметры корректно отображаются в адресной строке,
  • что при обновлении страницы состояние сохраняется,
  • что переход по "Назад"/"Вперед" возвращает правильное состояние.

Для удобства разработки можно использовать Vue Devtools: в разделе router наглядно видно актуальные параметры запроса.

Заключение

Работа с query-параметрами в маршрутах Vue — мощный и универсальный инструмент для управления отображением, навигацией и состоянием приложения. Используя возможности vue-router, вы легко считаете, обновляете и валидируете значения параметров запроса. Старайтесь всегда учитывать граничные случаи, валидировать значения и поддерживать чистоту логики обработки. Ваши пользователи получат более устойчивое и предсказуемое поведение интерфейса, а вы — удобство поддержки и развития кода.


Частозадаваемые технические вопросы по теме

Как получить query-параметры при серверном рендеринге во Vue и Nuxt?

В Nuxt вы получаете параметры через context.query в asyncData или через $route.query во Vue-компоненте:

export default {
  async asyncData({ query }) {
    // query содержит все параметры запроса
    return { ... }
  }
}

Как удалять отдельный query-параметр, не затрагивая остальные?

При удалении одного параметра создайте новый объект без ненужного параметра:

const { page, ...rest } = this.$route.query
this.$router.push({ path: this.$route.path, query: rest })

Как сериализовать и использовать массивы в query-параметрах корректно?

Vue Router позволяет использовать несколько одноимённых параметров:

this.$router.push({ query: { color: ['red', 'green', 'blue'] } })

URL выглядит: /products?color=red&color=green&color=blue

Как сделать reset (очистку) всех параметров и вернуться к дефолтам после фильтрации?

Передайте пустой объект в query:

this.$router.push({ path: this.$route.path, query: {} })

Или только нужные дефолтные значения:

this.$router.push({ path: this.$route.path, query: { page: 1 } })

Как синхронизировать состояние фильтров с query-параметрами при загрузке страницы?

В методе mounted или через watch инициализируйте состояние фильтров исходя из $route.query:

mounted() {
  this.selectedCategory = this.$route.query.category || 'all'
  this.currentPage = Number(this.$route.query.page || 1)
}

Это позволит фильтрам всегда быть в sync с адресной строкой.

Работа с JSON данными в приложениях VueСтрелочка вправо

Все гайды по Vue

Работа с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueОбзор популярных шаблонов и стартовых проектов на VueКак организовать страницы и маршруты в проекте на VueСоздание серверных приложений на Vue с помощью Nuxt jsРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияНастройка и сборка проектов Vue с использованием современных инструментов
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование метода map в Vue для обработки массивовОбработка пользовательского ввода в Vue.jsОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitИспользование директив и их особенности на Vue с помощью defineСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в Vue
Открыть базу знаний