Props в маршрутах

Vue Router предоставляет мощный механизм передачи данных в компоненты через свойства props. Использование props вместо $route.params или $route.query делает компоненты более чистыми, переиспользуемыми и тестируемыми, так как компоненты получают данные напрямую через стандартный интерфейс Vue, а не через глобальный объект маршрута.


Включение props в маршруте

Чтобы маршрут передавал данные через props, необходимо добавить в его конфигурацию свойство props. Vue Router поддерживает несколько способов передачи props:

const routes = [
  {
    path: '/user/:id',
    component: User,
    props: true
  }
]

Ключевые моменты:

  • Если props установлено в true, все параметры маршрута (params) автоматически передаются в компонент как props.
  • Компонент User может напрямую использовать id как свойство:
export default {
  props: ['id'],
  mounted() {
    console.log(this.id)
  }
}

Использование объекта для передачи props

Помимо передачи params напрямую, можно использовать объект, чтобы задать статические props:

const routes = [
  {
    path: '/about',
    component: About,
    props: { title: 'О проекте', showHeader: true }
  }
]

В этом случае компонент About получит два props: title и showHeader с указанными значениями.


Функция для динамических props

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

const routes = [
  {
    path: '/search',
    component: SearchResults,
    props: route => ({ query: route.query.q })
  }
]

Особенности этого подхода:

  • Аргумент функции route содержит объект маршрута.
  • Можно возвращать объект, формируя props на основе params, query или любого другого свойства маршрута.
  • Обеспечивает полную динамическую настройку передачи данных.

Пример использования в компоненте:

export default {
  props: ['query'],
  watch: {
    query(newValue) {
      this.fetchResults(newValue)
    }
  },
  methods: {
    fetchResults(searchTerm) {
      // логика запроса на сервер
    }
  }
}

Отличие props от $route

Использование props:

  • Компонент не зависит от маршрутизатора, легко тестируется.
  • Props обновляются при изменении маршрута, если используется динамическая функция.
  • Чистая декларативная передача данных.

Использование $route внутри компонента:

  • Привязка напрямую к маршруту делает компонент зависимым от Vue Router.
  • Необходимость вручную следить за изменением $route.params или $route.query.
  • Сложнее тестировать компонент отдельно.

Работа с вложенными маршрутами и props

Вложенные маршруты (children) также поддерживают props. Пример:

const routes = [
  {
    path: '/users/:userId',
    component: UserLayout,
    props: true,
    children: [
      {
        path: 'profile',
        component: UserProfile,
        props: route => ({ userId: route.params.userId })
      }
    ]
  }
]

Особенности:

  • Родительский компонент может получить userId через props.
  • Дочерний компонент также получает тот же userId, если это требуется.
  • Функция позволяет модифицировать или комбинировать параметры для дочерних компонентов.

Ограничения и нюансы

  • Передача props через маршруты работает только для компонентов, указанных в конфигурации маршрута. Компоненты, встроенные внутри других, не получают их автоматически.
  • При использовании динамической функции props следует учитывать обновление маршрута, особенно если компонент уже смонтирован. В некоторых случаях нужно использовать watch для отслеживания изменений props.
  • Если маршрут использует несколько params и query, можно комбинировать их при помощи функции для props:
props: route => ({
  id: route.params.id,
  filter: route.query.filter || 'all'
})

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