- Переход Vue.js 2.0 по динамическому маршруту не срабатывает
- 2 ответа
- Почему путь в ссылке меняется и переход по этому адресу не выполняется (Vue-router)?
- # Сбои при навигации
- # Обнаружение сбоев навигации
- # Тип NavigationFailureType
- # Свойства ошибок навигации
- Почему путь в ссылке меняется и переход по этому адресу не выполняется (Vue-router)?
- Роутинг в Vue
- Роутинг в Vue
- ведущий разработчик NGRSOFTLAB
- Базовые вещи
- Минимальная конфигурация
- Иерархия путей
- Параметры (Props) маршрута
- Метаданные (meta) маршрута
- Глубже (nested children)
- Пояснение за Path
- Шире (несколько router-view)
- Страница ошибки 404
- Защита маршрутов
- Навигация между маршрутами
- Программная навигация
- Компонент routerLink
- Лучшие практики
- Продвинутые приемы
- Разбиение прав по уровням доступа
- Анимация переходов между страницами
- Индикация загрузки при переходе между роутами
- Изменение тайтлов при переходе между роутами
- Плавный скролл по странице при переходе вперед/назад
Переход Vue.js 2.0 по динамическому маршруту не срабатывает
Я обнаружил, что переход не идет по динамическому маршруту с параметрами. Например, с помощью приведенного ниже кода, когда я нахожусь в /chapter/1 и перехожу в /chapter/2 , переход отсутствует. Но когда я в /chapter/1 и иду в /profile/1 , есть один!
Может быть, это связано с тем, что vue-router не уничтожает родительский компонент? Я не нашел способ запустить переход из кода. Я попробовал эту конфигурацию в примере пакета vue-router, и поведение тем же.
При использовании маршрутов с параметрами следует обратить внимание на то, что при переходе пользователя из / user / foo в / user / bar один и тот же экземпляр компонента будет использоваться повторно. Поскольку оба маршрута отображают один и тот же компонент, это более эффективно, чем уничтожение старого экземпляра и создание нового. Однако это также означает, что перехватчики жизненного цикла компонента не будут вызываться.
Чтобы реагировать на изменения параметров в том же компоненте, вы можете просто наблюдать объект $ route
Должен ли я опубликовать вопрос?
Спасибо за вашу помощь !
2 ответа
Можете ли вы проверить этот рабочий пример: https://jsfiddle.net/mani04/dLnz4rbL/
Я пытался использовать метод, описанный в переход между элементами в документации.
В моем примере скрипта, который в основном использует код из вашего описания вопроса, я использовал оболочку transition внутри компонента, как показано ниже:
В документе указывается, что нам нужно предоставить key , чтобы сделать их различными элементами для Vue.js. Поэтому я добавил ваш идентификатор главы в качестве ключа.
Я не знаю, является ли это хаком или правильным решением, я перешел с Angular2 на Vue только 2 недели назад. Но пока кто-то не даст вам лучшего решения, вы можете использовать этот метод для получения переходов для динамических маршрутов.
Что касается публикации этого сообщения в качестве проблемы на странице github vue-router , я не уверен, что это может быть исправлено, но вы, безусловно, можете сообщить об этом. Исправление может включать не повторное использование компонентов, что также не идеально. Так что это сложный вызов для них. Но обсуждение обязательно должно быть интересным! Пожалуйста, опубликуйте ссылку на вопрос здесь, если вы решите ее создать 🙂
Пришел сюда с той же проблемой, и ответ @ Мани работает отлично. Но мне не очень нравится идея использовать два
Поэтому я попытался поместить key в . И это работает! Рабочий пример: https://codepen.io/widyakumara/details/owVYrW/
Не уверен, что это правильный способ ведения дел, я вроде как использую vue.
PS . Я использую Vue 2.4.1 и Vue Router 2.7.0
Источник
Почему путь в ссылке меняется и переход по этому адресу не выполняется (Vue-router)?
Мой проект на ГитХаб
Код главной страницы:
Код страницы для перехода:
- Вопрос задан более двух лет назад
- 590 просмотров
Не вижу router-view . Где он? Должен быть. Надо добавить.
UPD. Глянул остальной код — дичь какая-то.
Должен ли пользователь одновременно видеть компоненты Pagination и Detail? Чё-то сомнительно. Наверное, стоит сделать для pagination отдельный роут, который будет доступен по дефолту (?). А если какая-то его часть ( .header ?) должна быть доступна везде — её можно вынести в компонент App (в котором следует разместить router-view ).
Компонент Pagination. Почему при создании router-link вы в качестве id используете индекс? Вместо
Источник
# Сбои при навигации
При использовании router-link Vue Router вызывает router.push для запуска навигации. В большинстве случаев ожидаемое поведение ссылок заключается в переходе на новую страницу, но есть несколько ситуаций при которых пользователь остаётся на той же странице:
- Пользователь уже находится на странице, на которую пытается перейти
- Навигационный хук прерывает навигацию вызовом next(false)
- Навигационный хук выбрасывает ошибку или вызывает next(new Error())
При использовании компонента router-link ни один из этих случаев не будет логироваться как ошибка. Однако при использовании router.push или router.replace можно столкнуться с сообщением «Uncaught (in promise) Error» после которого в консоли последует более конкретное сообщение. Давайте разберемся как отличать сбои навигации.
В версии 3.2.0, навигационные сбои доступны через два необязательных коллбэка router.push : onComplete и onAbort . Начиная с версии 3.1.0, router.push и router.replace возвращают Promise если не указаны коллбэки onComplete / onAbort . Этот Promise разрешается вместо вызова onComplete и отклоняется вместо вызова onAbort .
# Обнаружение сбоев навигации
Сбой навигации будет экземпляром Error с парой дополнительных свойств. Проверить произошла ли ошибка в маршрутизаторе можно с помощью функции isNavigationFailure :
Если опустить второй параметр в isNavigationFailure(failure) , то будет проверяться только, является ли ошибка сбоем навигации.
# Тип NavigationFailureType
Тип NavigationFailureType поможет разработчикам определять тип навигационного сбоя. Существует 4 различных типа:
- redirected : внутри навигационного хука был вызван next(newLocation) для перенаправления в другое место.
- aborted : внутри навигационного хука был вызван next(false) для отмены навигации.
- cancelled : произошла полностью новая навигация до того, как текущая могла закончиться. Например, во время ожидания внутри навигационного хука был вызван router.push .
- duplicated : навигация была предотвращена, потому что уже находимся в месте назначения.
# Свойства ошибок навигации
Все сбои навигации предоставляют доступ к свойствам to и from , отображающие для навигации в которой произошёл сбой местоположение места назначения и текущее местоположение соответственно:
Во всех случаях значения to и from будут объектами нормализованных маршрутов.
Источник
Почему путь в ссылке меняется и переход по этому адресу не выполняется (Vue-router)?
Мой проект на ГитХаб
Код главной страницы:
Код страницы для перехода:
- Вопрос задан более двух лет назад
- 590 просмотров
Не вижу router-view . Где он? Должен быть. Надо добавить.
UPD. Глянул остальной код — дичь какая-то.
Должен ли пользователь одновременно видеть компоненты Pagination и Detail? Чё-то сомнительно. Наверное, стоит сделать для pagination отдельный роут, который будет доступен по дефолту (?). А если какая-то его часть ( .header ?) должна быть доступна везде — её можно вынести в компонент App (в котором следует разместить router-view ).
Компонент Pagination. Почему при создании router-link вы в качестве id используете индекс? Вместо
Источник
Роутинг в Vue
Роутинг в Vue
ведущий разработчик NGRSOFTLAB
С появлением веб-приложений пришла потребность в смене URL-адресов с помощью JS. На помощь пришел History API браузера.
Благодаря этому все основные современные фреймворки позволяют программно управлять маршрутизацией с синхронизацией URL-адреса с представлением приложения.
Для маршрутизации во Vue-приложениях можно создать свою собственную интеграцию с History API, но лучше использовать официальную библиотеку от Vue — Vue-Router.
Базовые вещи
Использование можно начать хоть с установки с CDN:
Но мы начнем сразу с «правильного» варианта — с Vue Cli:
Создадим проект с помощью VUE CLI с базовым шаблоном — Default ([Vue 2] babel, eslint):
vue create vue-router-test-app
Минимальная конфигурация
Добавим в Main.js минимальную конфигурацию для роутера:
Роуты представляют собой массив, каждый элемент которого — объект, где требуется указать path и component .
26 октября в 18:00, Онлайн, Беcплатно
Чтобы увидеть изменения надо вывести компонент роутера — routerView , который отвечает за отображение. Для этого изменим App.vue:
Теперь, зайдем на http://localhost:8080/. Увидим страницу с маршрутом «/», где отображается компонент HelloWorld.vue, вместо тега router-view , который мы писали в App.vue.
Иерархия путей
Добавим маршрут в main.js (массив routes ):
Зайдем по адресу http://localhost:8080/board. Увидим вторую страницу с отображением рендер-функции.
Параметры (Props) маршрута
Поправим дочерний маршрут для маршрута /board в main.js. Для дочерних компонентов надо указывать где в родительском компоненте отображать дочерние — компонентом router-view . В нашем случае — это в рендер-функция:
Напомню, что рендер-функция в template-представлении будет выглядеть следующим образом:
Создадим компонент Board.vue с содержимым:
Перейдем по адресу http://localhost:8080/board/21 и увидим родительский и дочерний компоненты Board с передачей параметра id равным 21.
Параметры маршрута доступны в компоненте по this.$route.params .
Если хотим более явно отобразить зависимость компонента от входных параметров, используем настройку props: true при настройке маршрута:
А в компоненте Board.vue принять id как входной параметр компонента:
Метаданные (meta) маршрута
Теперь мы можем обратиться к метаданным роута из компонента HelloWorld.vue следующим образом:
Глубже (nested children)
В дочерние компоненты можно углубляться до бесконечности (до ограничений сервера).
Сделаем дочерний роут для дочернего роута.
Рендер-функция теперь записана обычной функцией, т.к. нужен контекст компонента.
Передаем дочернему компоненту дочернего компонента параметры через компонент router-view как обычному компоненту. Звучит сложно, но интуитивно понятно. И так, спускаем пропсы в дочернем — дочернему дочернего:
Пояснение за Path
Запись вида path: «child» означает, что мы обращаемся к пути родителя и продолжаем его путь:
Из дочернего компонента можно сослаться на любой другой уровень роута:
Эта запись обрабатывает страницу с адресом: http://localhost:8080/first-level.
Шире (несколько router-view)
Можно использовать несколько router-view в 1 компоненте. Для этого в конфигурации маршрутов (routes) пишем вместо component — components, который принимает объект, где ключ — атрибут name у router-view . Если указать ключ «default», то такой компонент будет отображаться, если router-view безымянный (без атрибута name ).
Перейдем по адресу: http://localhost:8080/board/23/child и увидим небольшой интерактив с переключением активных router-view.
Страница ошибки 404
Чтобы создать страницу ошибки, достаточно положить в конец списка маршрутов такую конструкцию:
Теперь, при переходе по несуществующему пути (например — http://localhost:8080/mistake), будет выведен компонент ошибки.
Лучше писать в таком виде:
Теперь у нас есть страница с ошибкой, куда мы можем со спокойной совестью переадресовывать пользователей (вдруг когда-нибудь понадобится это делать).
Защита маршрутов
Защиту маршрутов осуществляют с использованием метаданных маршрутов и хука beforeEach роутера.
Теперь, при попытке получить доступ к странице, которая требует авторизации, нас перебросит на страницу /auth-required.
Навигация между маршрутами
Программная навигация
Программная навигация может вызываться из любого места вашего приложения таким образом:
Если мы хотим передать параметры, нам нужно использовать другой подход, основанный на использовании имен роутов.
Укажем имя роуту /board/:id :
Теперь мы можем передавать параметры:
Получим ошибку «Invalid prop: type check failed for prop «id». Expected String with value «100500», got Number with value 100500».
Причина в том, что url — это всегда тип данных String , а мы передали программно id с типом Number . Исправляется это просто: перечислим возможные типы данных в компоненте.
Компонент routerLink
Компонент routerLink позволяет создавать ссылки внутри сайта, которые преобразуются в «нативные» браузерные ссылки (тег ):
К таким ссылкам автоматически могут добавляться классы:
- router-link-exact-active — точное совпадение;
- router-link-active — частичное (активен дочерний компонент указанного в атрибуте to роута).
Чтобы не отображать активный класс родительских, достаточно написать атрибут exact :
Мы можем переопределить создаваемый элемент:
К сожалению, в таком случае, классы не проставляются.
Также можем передавать объект:
Лучшие практики
Этот раздел мы посвятим рефакторингу того, что мы написали выше.
Создаем структуру папок для роутера:
Перенесем в router.js все, что касается настроек роутера:
Перенесем routes.js все, что касается настроек маршрутов.
И сразу заменим импорты на динамические.
Если у Вас уже прописано много роутов, ручное изменение может потребовать много времени. Поможет регулярка:
const $1 = () => import(/* webpackChunkName: «$1» */ $2)
Теперь в Chrome Dev Tools во вкладке Network будет видно когда-какой компонент грузится из сети, а раньше все роуты загружались сразу в 1 мега-бандле.
Продвинутые приемы
Под «продвинутостью» подразумевается «приятность» их использования. К таким приемам можно отнести, например, такие темы как:
- разбиение прав по уровням доступа;
- анимацию переходов между страницами;
- индикацию загрузки при переходе между роутами;
- изменение тайтлов при переходе между роутами;
- плавный скролл по странице при переходе назад;
- и т.п.
Итак, обо всем по-порядку.
Разбиение прав по уровням доступа
Бывает ситуация, когда у пользователей бывает более двух состояний: не только авторизация, но и другие. Например, платная подписка. С этих пор мы задумываемся про неограниченный уровень разделения прав. Делается это буквально парой десятков строчек кода, но для краткости, удобства и чтобы не изобретать велосипед, мы будем использовать готовую библиотеку. Установим ее:
yarn add vue-router-middleware-plugin
Создадим специальные файлы middleware для проверки прав пользователей:
В последнем листинге, приведен пример асинхронной проверки, что значит — можно обращаться в actions стора и делать запросы на сервер.
Теперь поставим проверку на авторизацию на все роуты, а затем сделаем исключения для некоторых роутов:
Теперь разберемся с конкретными маршрутами.
Поработаем над архитектурой нашего приложения, чтобы сделать его более предсказуемым. Сделаем отдельный шаблон Auth.vue и положим его в pages, а компоненты, которые там используются, т.е. в разделе /auth, положим в соответствующий раздел components.
Т.о. получается удобная структура:
Создадим вспомогательную функцию для генерации подобных роутов genAuthRoutes .
Удаляем глобальную проверку на авторизацию в свойстве ignore и добавляем другую проверку в свойстве attach объекта meta.middleware :
- src/components/auth/Login.vue;
- src/components/auth/Register.vue;
- src/components/auth/Forgot.vue,
с типовым шаблоном:
Также отрефакторим страницу Board , назовем его MainBoard
Соответственно, добавляем компоненты в соответствующую категорию в components:
Осталось отрефакторить главный компонент — App.vue:
Теперь, снимем отметку с «Logged In» и попробуем перейти по маршруту http://localhost:8080/board. Нас незамедлительно переадресует на страницу «auth-required».
Поставим отметку на «Logged In», снимем с «Has License» и перейдем по маршруту http://localhost:8080/board/33/child. Нас перенесет на страницу license, однако, если снять отметку с «Logged In» и обновить страницу, то мы снова перейдем на страницу «auth-required».
Теперь проверим, можно ли зайти на страницу авторизации, когда пользователь уже прошел авторизацию. Поставим отметку «Logged In» и перейдем по адресу http://localhost:8080/auth/register. Нас перебросит на главную страницу.
Анимация переходов между страницами
Это просто. Оборачиваем главный RouterView компонентом анимации transition и добавляем стили:
Индикация загрузки при переходе между роутами
Это тоже просто. Ставим библиотеку nprogress:
yarn add nprogress
Добавляем в router.js:
Изменение тайтлов при переходе между роутами
И это тоже просто.
Заполняем meta.title маршрутам и ставим document.title каждой странице в хуке beforeEach :
Плавный скролл по странице при переходе вперед/назад
Когда жмешь по браузерным «системным» кнопкам назад или вперед, браузер запоминает положение прокрутки и возвращает. Такое поведение мы можем повторить.
Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.
Перейти к регистрации
Источник