Vue3 Маршрутизация (Vue Router)

В этой главе мы рассмотрим маршрутизацию Vue.

Маршрутизация Vue позволяет нам получать доступ к различному содержимому через разные URL.

С помощью Vue мы можем реализовывать одностраничные веб-приложения (SPA) с несколькими представлениями.

Маршрутизация Vue.js требует загрузки библиотекиvue-router

URL документации на китайском:документация vue-router。

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

На рисунке выше показанадвухуровневая вложенная структура маршрутов:

  • верхнего уровня (App.vueиз<router-view>)отвечает за рендеринготдельных макетов(например,Login.vue) илимакет основного каркаса(Layout.vue)。
  • макет основного каркаса (Layout.vue)внутри содержит второй<router-view>, используемый для рендерингадочерних компонентов функциональной страницы(например,Dashboard.vue、User.vue), таким образом обеспечивая постоянное отображение верхней панели, боковой панели и нижнего колонтитула.
  • Несовпадающие пути в конечном итоге приведут к независимомуpage404.vue。

Основные компоненты

Компонент Описание Доступ через Options API Доступ через Composition API
routerЭкземпляр Экземпляр всей системы маршрутизации, используемый для глобальной навигации, добавления маршрутов и т. д. this.$router useRouter()
routeObject Объект текущего активного состояния маршрута, содержащий такую информацию, как текущий URL, параметры, query и т. д. this.$route useRoute()
<router-link> Компонент, используемый для навигации в приложении; он будет отрендерен как<a>тег, но может предотвратить стандартную перезагрузку страницы. - -
<router-view> Компонент, сопоставленный маршруту, будет отрендерен в этой позиции. - -

Установка

Установка с помощью npm

npm install vue-router

npm (Китайское зеркало)

Рекомендуется использовать зеркало Taobao:

npm install -g cnpm --registry=https://registry.npmmirror.com
cnpm install vue-router@4

Прямая загрузка / CDN

https://unpkg.com/vue-router@4

Базовое использование

1. Создайте таблицу маршрутизации

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

export default createRouter({
  history: createWebHistory(),
  routes
})

2. Смонтируйте в приложении

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

3. Место вывода страницы

<router-view></router-view>

4. Навигация

<router-link to="/about">About</router-link>

5. Динамическая маршрутизация

{ path: '/user/:id', component: User }

При посещении /user/10, $route.params.id === '10'.

6. Ленивая загрузка

const About = () => import('../views/About.vue')

7. Навигационные хуки (аутентификация)

router.beforeEach((to, from, next) => {
  next()
})

8. Перенаправление

{ path: '/old', redirect: '/' }

9、404

{ path: '/:pathMatch(.*)*', component: NotFound }

Простой пример

Vue.js + vue-router позволяют легко реализовать одностраничное приложение.

<router-link>— это компонент, используемый для создания навигационной ссылки для переключения между различным содержимым HTML.toАтрибут `to` — это адрес назначения, т. е. содержимое, которое нужно отобразить.

В следующем примере мы добавляем vue-router, затем настраиваем сопоставления компонентов и маршрутов, а затем сообщаем vue-router, где их отображать. Код выглядит следующим образом:

HTML-код

<div id="app"> <h1>Привет, App!</h1> <p> <!--Используйте компонент router-link для навигации--> <!--Укажите ссылку, передав `to`--> <!--`<router-link>` отрендерит тег `<a>` с правильным атрибутом `href`--> <router-link to="/">Перейти на главную</router-link> <router-link to="/about">Перейти на страницу About</router-link> </p> <!--Router View--> <!--Компонент, соответствующий маршруту, будет отрисован здесь.--> <router-view></router-view> </div>

router-link

Обратите внимание, что мы не использовали обычный тег `<a>`, а вместо этого использовали пользовательский компонент `router-link` для создания ссылок. Это позволяет Vue Router изменять URL без перезагрузки страницы и обрабатывать генерацию и кодирование URL. Позже мы увидим, как воспользоваться этими возможностями.

router-view

`router-view` отобразит компонент, соответствующий URL. Вы можете поместить его куда угодно, чтобы он соответствовал вашему макету.

Код JavaScript

//1. Определите компоненты маршрутов. //Они также могут быть импортированы из других файлов. const Home = { template: '<div>Home</div>' } const About = { template: '<div>About</div>' } //2. Определите несколько маршрутов //Каждый маршрут должен сопоставляться с компонентом. //Позже мы обсудим вложенные маршруты. const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, ] //3. Создайте экземпляр маршрутизатора и передайте конфигурацию `routes` //Здесь можно добавить больше конфигурации, но пока мы //оставляем всё простым. const router = VueRouter.createRouter({ //4. Внутри предоставляется реализация режима history. Для простоты здесь мы используем режим hash. history: VueRouter.createWebHashHistory(), routes, //Сокращение для `routes: routes` }) //5. Создайте и смонтируйте корневой экземпляр. const app = Vue.createApp({}) //Убедитесь, что вы _используете_ экземпляр роутера, чтобы //всё приложение поддерживает маршрутизацию. app.use(router) app.mount('#app') //Теперь приложение запущено!

Попробуйте »

У нажатых навигационных ссылок будут добавлены стилиclass ="router-link-exact-active router-link-active"。

Пример приложения

Следующий пример охватывает следующие аспекты маршрутизации:Определение、Создание、Монтирование、НавигацияиРендерингпять основных шагов.

1. main.js (входной файл)

Пример

import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // Импортируйте настроенный экземпляр роутера

// 1. Создайте экземпляр приложения Vue
const app = createApp(App);

// 2. Смонтируйте роутер
app.use(router);

// 3. Смонтировать в DOM
app.mount('#app');

2. router/index.js (конфигурация маршрутов)

Пример

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

// Импорт компонентов маршрутов (используем синхронные импорты для упрощения примера)
const Home = { template: '<h2>Главная страница</h2><p>Добро пожаловать на главную страницу приложения!</p>' };
const About = { template: '<h2>О нас</h2><p>Узнайте больше об этом проекте.</p>' };

// Определяем массив записей маршрутов
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  // Совпадение 404 (разместите его последним)
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: { template: '<div>404 Не найдено</div>' }
  }
];

// Создать экземпляр Router
const router = createRouter({
  // Использовать режим HTML5 History (рекомендуется)
  history: createWebHistory(),
  routes, // Конфигурация маршрутов
});

export default router;

3. App.vue (корневой компонент)

Пример

<template>
  <div>
    <h1>Пример Vue Router</h1>
   
    <nav>
      <router-link to="/" active-class="active-link">Главная</router-link> |
      <router-link to="/about" active-class="active-link">О нас</router-link> |
      <router-link to="/nonexistent">Демо 404</router-link>
    </nav>
   
    <hr>
   
    <main>
      <router-view></router-view>
    </main>
  </div>
</template>

<style>
/* Простые стили активной ссылки */
.active-link {
  font-weight: bold;
color: #427EB9; /* Зелёный Vue */
}
/* Настройка отступов между ссылками */
nav a {
  margin: 0 5px;
  text-decoration: none;
}
</style>

Когда вы запустите это приложение:

  • Нажмите ссылкуHome, URL изменится на/,<router-view>отображается вHome Pageсодержимое компонента.
  • Нажмите ссылкуAbout, URL изменится на/about,<router-view>отображается вAbout Usсодержимое компонента.
  • Нажмите ссылку404 Demo, URL изменится на/nonexistent,<router-view>отображается в404 Not Foundсодержимое компонента.

Связанные атрибуты <router-link>

Далее давайте подробнее рассмотрим атрибуты <router-link>.

в

Представляет ссылку на целевой маршрут. При клике значение `to` немедленно передаётся в `router.push()`, поэтому это значение может быть строкой или объектом, описывающим целевую локацию.

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home.html">Home</a>

<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

замена

Если установлен атрибут replace, при клике будет вызван router.replace() вместо router.push(), и после навигации не останется записи в истории.

<router-link :to="{ path: '/abc'}" replace></router-link>

append

Когда установлен атрибут append, путь добавляется в начало текущего (относительного) пути. Например, если мы переходим из /a по относительному пути b, без append путь будет /b, а с append — /a/b.

<router-link :to="{ path: 'relative/path'}" append></router-link>

тег

Иногда вы хотите<router-link>отображаться как определённый тег, например<li>.tagПоэтому мы используем

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

active-class

prop, чтобы указать, какой тег. Он по-прежнему прослушивает клики и запускает навигацию.

<style>
   ._active{
      background-color : red;
   }
</style>
<p>
   <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

Set the CSS class name used when the link is active. It can be replaced by the following code.classОбратите внимание здесьactive-class="_active"。

exact-active-class

использовать

<p>
   <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

event

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

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

Приведённый выше код устанавливает событие в mouseover, и когда мышь наводится на Router Link 1, HTML-содержимое, к которому выполнен переход, изменится.


Справочник по основному API Vue Router (v4, Vue 3)

I.createRouterПараметры конфигурации

Элемент конфигурации Назначение Пример
history Укажите режим URL createWebHistory()
routes Массив определения таблицы маршрутов [{ path: '/', component: Home }]
scrollBehavior Управление позицией прокрутки страницы { top: 0 }
strict Строго ли различать завершающие слеши true
linkActiveClass Класс, когда ссылка активна 'active'
linkExactActiveClass Класс, когда ссылка точно активна 'exact-active'
parseQuery Пользовательский разбор query-параметров URL (q) => ({...})
stringifyQuery Пользовательская сериализация query-параметров URL (obj) => 'a=1'

II. Фабрика History

API Назначение Пример
createWebHistory() Использовать режим HTML5 History (рекомендуется) createWebHistory()
createWebHashHistory() Использовать режим Hash (URL содержит#) createWebHashHistory()
createMemoryHistory() Подходит для SSR (рендеринг на стороне сервера) createMemoryHistory()

III.RouteRecord(Запись маршрута)

Поле Назначение Пример
path Определение пути маршрута /user/:id
name Именование маршрута name: 'User'
component Соответствующий основной компонент UserView
components Для именованных представлений (несколько<router-view>) { default: A, left: B }
redirect Цель перенаправления redirect: '/login'
children Определение вложенных дочерних маршрутов [ { path: 'profile' } ]
props будетparamsАвтоматическое преобразование в компонентprops props: true
meta Пользовательское поле метаинформации { auth: true }
alias Добавление псевдонимов для текущего маршрута (несколько записей) alias: '/b'
beforeEnter Навигационный хук для конкретного маршрута { beforeEnter: (to,from,next)=>{} }

IV. Навигация Router (методы экземпляра Router)

API маршрутизатора Назначение Пример
router.push(to) Программная навигация, добавляет новую запись в стек истории router.push('/a')
router.replace(to) Программная навигация, заменяет текущую запись истории router.replace('/a')
router.back() Вернуться на один шаг назад router.back()
router.forward() Перейти на один шаг вперёд router.forward()
router.go(n) Вручную сместить стек истории router.go(-1)
router.addRoute(route) Динамически добавить записи маршрутов router.addRoute({ name:'Post', ... })
router.removeRoute(name) Удалить записи маршрутов по имени router.removeRoute('user')
router.getRoutes() Получить все записи маршрутов router.getRoutes()
router.hasRoute(name) Определить, существует ли маршрут с указанным именем router.hasRoute('user')

V. Навигационные хуки

Хук Область действия Сигнатура хука
router.beforeEach Глобальный before (to, from, next) => {}
router.beforeResolve Глобальная фаза resolve (после выполнения внутрикомпонентных хуков и разрешения асинхронных компонентов) (to, from, next) => {}
router.afterEach Глобальный after (не может предотвратить навигацию) (to, from, failure) => {}
beforeEnter Специфичный для маршрута beforeEnter: (to, from, next) => {}
beforeRouteEnter Внутрикомпонентный (не имеет доступаthis) beforeRouteEnter(to, from, next) {}
beforeRouteUpdate Внутрикомпонентный (когда текущий маршрут используется повторно, например, при изменении параметра) beforeRouteUpdate(to, from, next) {}
beforeRouteLeave Внутрикомпонентный (при выходе из этого компонента) beforeRouteLeave(to, from, next) {}

VI.<router-link>Пропсы

Пропсы Назначение Пример
to Адрес целевого маршрута to="/a"или:to="{ name: 'user', params: { id: 1 } }"
replace Использование во время навигацииrouter.replace() <router-link replace>
custom Пользовательский рендеринг, используемый со слотами <router-link custom v-slot="{ href }">
active-class Класс, применяемый, когда ссылка активна 'active'
exact-active-class Класс, применяемый при точном совпадении ссылки 'exact'

VII.<router-view>Пропсы

Пропсы Назначение Пример
name Используется для рендеринга multi-view (именованных представлений) <router-view name="left">
route (Для продвинутых) Принудительно указать объект маршрута для рендеринга <router-view :route="someRoute">

VIII.Route(Текущий объект маршрута)

Этот объект получается черезuseRoute()илиthis.$routeполучить.

Поле Type Значение Пример
params object Динамические параметры пути route.params.id
query object Параметры URL-запроса route.query.q
hash string Значение хэша в URL (с#) route.hash
fullPath string Полный разрешённый путь (включая query и hash) /user/1?x=1
name string Имя текущего маршрута 'User'
path string Текущий путь (без строки запроса и хэша) /user/1
meta object В конфигурации маршрутаmetaинформация route.meta.auth
matched RouteRecord[] Все записи, совпавшие с маршрутом (для вложенных маршрутов) route.matched

IX. Композиционный API

API Назначение Пример
useRoute() Получить объект текущего маршрута (Route) const route = useRoute()
useRouter() Получить экземпляр маршрутизатора (Router) const router = useRouter()

X. Программная навигация (полный пример)

Назначение Пример Примечания
Навигация по именованному маршруту router.push({ name:'User', params:{ id:10 } }) Рекомендуемый метод, не зависит от порядка путей
Навигация с параметрами запроса router.push({ path:'/search', query:{ q:'x' } }) Путь + параметры запроса
Push/replace с поддержкой await await router.push('/a') Навигация асинхронна, можно дождаться её завершения
Навигация с использованием объекта URL router.push({ path: '/foo', hash: '#bar' }) Полный контроль над деталями URL
Другие расширения