VUE дружим с Роутингом

С большими возможностями приходит и большая ответственность
! Человек паук

Сегодня мы разберем продвинутые техники идеального укрощения роутинга в реактивном фреймворке на примере VUE. Если вы совершаете переход от обычных страниц к реактивности - можете наткнуться на несколько камней, которые мало где описаны как можно решать правильно.
В чем же особенность роутинга в реактивных приложениях. А в том, что страница не перегружается полностью а происходит эмуляция обновления страницы, а именно изменяющейся части. Мы же реактивные, информацию в шапке и других общих частях (которая обычно располагается в папке layouts) и это здорово, потому что браузеру не нужно заново рендерить эту самую неизменную область схожую у нескольких страниц заново. А URL эмулируется либо через хеш # либо через History API

И всё тут складно и всё красиво ровно до тех пор, пока мы не замечаем проблему при переходе с одной страницы роутинга на ту же самую страницу. И почему-то контент не ведет себя аналогичным образом, компонент page на который смотрит роутинг не выполняет методы жизненного цикла create и mount и отсюда имеем не то поведение которое от него ожидаем

Ранее проблемы не возникало потому что не было возможности сохранить страницу и обновить только изменяемую часть.

Можно решить задачу тупо в лоб. Снести всю реактивность и поставить методы как привыкли, назовем метод refresh(). Нужно обновить  - вешаем метод который всё что нужно обновит на каждое событие которое может привести к изменению. Вот досада - нативные методы вперед-назад теперь не откликаются. Тут без реактивности не обойтись. У нас же есть наблюдатели watch, в которые можно запихнуть роутинг и следить за его изменением. Теперь все методы обновления можно делегировать ему.

замечательно. Роутинг сам следит за обновлением, вешать ничего нигде не надо. Вперед-назад также работает
Ну а теперь представьте что вы делаете приложение немножко круче чем стандартный блог. И что, на каждой странице, вам нужно готовить функцию для обновления? Так прекрасно жили ранее когда не было таких проблем. Может ну его, этот роутинг, отказаться и все дела.

Для тех кто не сдался - в запасе есть еще пара фокусов. Мы же всё ещё в javascript мире. Нам всё ещё доступны window.reload()
Если честно, очень грязный трюк. Крайне не рекомендую. Лучше возьмите на вооружение что-нибудь полегче, например такое

const to = this.$router.currentRoute
this.$router.replace("/")
this.$nextTick(() => this.$router.replace(to))

(нарыл в лучших рекомендациях на stackoverflow)

а теперь давайте познакомимся с одной интересной возможностью VUE - атрибут :key. Вы часто встречали его в циклах и списках, но он также может использоваться и для обычных элементов. Зачем он нужен? Он используется чтобы совмещать DOM дерево с виртуальным DOM шаблоном. Или как-то так. В общем элементы с одинаковым :key внутри компонента приводят к ошибке и перестают адекватно реагировать на изменение реактивности. Дополнительно при изменении этого самого :key - будет перерендерен сам элемент со всеми вытекающими. В общем то что нам нужно.
Теперь осталось связать наш любимый роутинг с этим самым :key на отслеживание. Как это сделать? Проще простого.

<router-view :key="$route.path"></router-view>

или даже не

<router-view :key="$route.fullPath"></router-view>

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

Хепи енд?
Смотрим что теперь получается. Теперь мы попали в другую крайность и стали заложниками маршрутизатора. При малейшем его изменении всегда и везде - будет обновление страницы (контента). Если у нас приложение сложнее чем портал с подстраницами 2го уровня и больше и общей шапкой, которую не нужно обновлять регулярно, чтобы экран не дергался, да и лишние запросы и нагрузка - вы же понимаете, мы обсуждали это всё чуть ранее. В общем не красиво это.
Это точно не хепи енд. И Даже nuxt тут не поможет

Теперь чтобы привнести мир в этом всё дело - мы можем просто добавить список исключений в параметр key для главного контента таким образом, чтобы он не менялся при переходе между подстраницами раздела. Сделать это можно легко с помощью computed выражения например с исключением на странице admin

<router-view :key="refreshablePath"></router-view>
computed: {
refreshablePath() {
// роут внутри admin исключение
if (this.$route.path.substr(0, 6) === "/admin") {
return this.$route.path.substr(0, 6)
}
return this.$route.fullPath
},
},

дополнительно на самой странице нужно повесить :key="$route.fullPath" на компоненте, который должен перенегеиться в зависимости от изменения роута внутри основной страницы.

да звучит хардкорно, и выглядит избыточно, чтобы для каждой такой страницы прописывать похожую конструкцию. Наверняка есть пусть элегантно уницифировать это на какие-нибудь нативные методы вроде meta тегов внутри роутов и какой-нибудь облегченной проверки через pathMatch
Об этом возможно вы услышите в следующей главе, или откопаете сами в качестве домашнего задания.

  • Автор: kosmom
  • Рейтинг: 0
  • Просмотров: 259
  • Комментариев: 0
  • Создан: 14.11.2020 05:37

Комментарии (0)

Ваши предложения и пожелания пишите на pro@kosmom.ru

Теги

backup bootstrap eloquent excel html ios javascript keep-alive laravel mvp php scroll timestamp undefined vue vuetify watch безопасность биометрический паспорт ваша любаша для путешествий загран на 10 лет загран паспорт загранпаспорт нового образца как заполнить анкеты кеширование логирование мцф образец заполнения антеты паспорт для путешествий паспорт нового поколения печать продукт проектирование прокси ремонт ремонт в апартаментах ремонт нежилого помещения самокат сколько стоил ремонт апартаментов спорт стандарты таблица хостинг цена ремонта юзабилити

Случайный пост

28.12.2012 13:05
Реализация качественного вывода данных. ч3. Сортировка