React и Vue: сильные стороны

Автор оригинала: Джон Дацеракис
  • Перевод
image Здравствуйте, коллеги. Мы возобновляем наши переводные публикации. Сегодняшний текст анонсирует давно назревшую новинку по веб-разработке, посвященную ультрасовременной библиотеке Vue.js. Учитывая, что у нас в ассортименте имеется сразу три отличные книги по React, а также книга по GraphQL, эта книга, несомненно, составит им хорошую компанию. О сильных сторонах Vue по сравнению с React – читайте под катом.

Многие разработчики любят сравнивать React и Vue. Кто-то останавливается на одном из этих фреймворков и упрямо придерживается его, даже не потрудившись познакомиться с другой библиотекой, которую когда-то отбраковал. Зачастую дело во времени: чтобы по-настоящему освоить все входы и выходы системы, с нею нужно работать, бороться и расти.

Конечно, неэффективно распыляться между схожими инструментами, но разве вам не любопытно? Мне – любопытно.

В интернете найдется множество сравнительных статей о том, как создать приложение в жанре «список дел» или т.п. с Vue и React, но реальные проекты редко бывают настолько просты. В реальном приложении приходится позаботиться о маршрутизации, сохранении состояния, совместимости плагинов, т.д.

Я заинтересовался не теми отличиями, что содержатся в базовой части библиотек Vue и React, а тем, каковы особенности создания реальных приложений при помощи этих фреймворков. Какой инструментарий удобнее, скажем, при разработке одностраничных приложений?

Приложения


Я использую Vue уже около двух лет, а веб-разработкой занимаюсь лет восемь. Впервые попробовав силы с Vue, я решил, что буду учить ее «в открытую», выложив в опенсорс простое приложение для ведения заметок, где будет возможность аутентификации пользователя при помощи JWT, а также полный набор CRUD-действий с заметками. В пару к нему я писал бэкендовое приложение, сделанное с использованием Koa.

Хотя, я и не испытывал острой необходимости менять фреймворк, я рассудил, что было бы неплохо выучить React. Поэтому я переделал на React мое приложение koa-vue-notes и также выложил его в опенсорс. Подумал, что такой опыт как минимум расширит мои представления о JavaScript, а, может быть, и найду себе новый любимый инструмент.

Вот домашняя страница моего приложения. Сверху – вариант с React, снизу – с Vue:

Хотя, я использую Bootstrap в моих приложениях все реже, обычно я внедряю в мои приложения новый компонент Navbar, появившийся в Bootstrap 4. Пытаясь повторить такое в Vue, я обнаружил, что Bootstrap-Vue – наилучший вариант для реализации Bootstrap 4. В React мои опыты и исследования привели меня к reactstrap.

В данном случае нужно отметить, что в конечном итоге я не стал использовать в React сетку Bootstrap, а остановился на варианте grid-styled, лучше сочетавшемся с применяемыми у меня styled-components – подробнее об этом ниже.

В приложении можно осуществлять с пользователем операции signup/login/forgot/reset, а с его заметками — create/read/edit/delete. Войдите в систему под demousername и demopassword, если лень регистрироваться.

Сравнение каталогов с исходным кодом


Первые впечатления


При работе с React сразу же становится очевидна одна вещь: придется очень плотно иметь дело с JavaScript.

Я придерживаюсь минималистических тенденций и стараюсь избавляться от всего хлама, который мне не нужен. Поэтому легко понять, насколько привлек меня React своей дешевой и сердитой природой.

Сравнение React-Router и Vue-Router


React-Router – это активно применяемая система маршрутизации для React. Скорость у нее отличная, однако, имея с ней дело на практике, я сталкивался с некоторыми интересными проблемами. Базовая настройка совсем простая, хотя, я не фанат объявления маршрутов прямо в HTML, как это требуется делать в React-Router v4 (в более ранних версиях React-Router ситуация была иная).

Продолжая препарировать мои маршруты, я повстречал такую проблему: как не допустить пользователей на те страницы, к которым у них не должно быть доступа. Элементарный пример: пользователь пытается открыть страницу типа account, не выполнив вход в систему. Потребовалось потратить не один час на изучение ситуации и действия методом проб и ошибок, чтобы выдать окончательное решение с применением React-Router.

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

image

Vue-Router – это собственная библиотека Vue, предназначенная для маршрутизации. Мне в самом деле нравится, как там можно добавлять дополнительную информацию к определениям маршрутов прямо в файле с объявлением маршрута. Посмотрите, как я закрыл пользователям доступ к страницам в Vue-Router при помощи свойства requiresAuth в определении маршрута и проверил истинность в функции router.beforeEach:

image

Теперь, когда мы рассмотрим код Vue, он кажется немного пространным, но именно так он и описан в документации, поэтому мне не составило труда настроить приложение. Не могу сказать того же о коде React; там, чтобы довести до ума такое же решение, мне потребовалось несколько часов. Когда в приложении требуется запрограммировать такую существенную функцию, как недопуск пользователей на те страницы, которые им не положено видеть… на такую работу не должна уходить целая ночь.

Далее, когда я пытался собирать по URL некоторые данные со страницы Edit, я обнаружил, что в самой свежей версии React-Router такая возможность оказалась удалена. Меня это… разочаровало. Думаю, я понимаю, зачем это было сделано: данные в строке запроса поступают во всевозможных видах и формах, но, позвольте, если даже параметр по URL взять невозможно – это как-то чересчур. Мне пришлось скачать библиотеку qs, чтобы правильно разбирать URL, и в ней также нашлись свои процедурные причуды. Подробное обсуждение – здесь.

На все про все, чтобы во всем разобраться, я потратил лишний час. Не самая серьезная проблема, однако, она разительно отличается от того опыта, что мне выпал с Vue-Router, а именно: поищи в документации и реализуй решение в коде. Я не пытаюсь сказать, что с Vue – не жизнь, а сказка; просто в случае с React у меня сложилось впечатление, как будто путь выдался заметно тернистее, нежели я ожидал.

Сравнение Redux и Vuex


Redux – это самое популярное хранилище данных в React, построенное по шаблону Flux. Если Flux вам не известен, поясню: это паттерн проектирования, в целом, основанный на однонаправленном потоке данных, организуемом путем диспетчеризации действий изнутри приложения. Иными словами, он все поддерживает в порядке, когда вы пытаетесь обращаться к данным из всевозможных ваших компонентов и манипулировать этими компонентами.
Вот для примера файлы из нашего хранилища Redux, где мы создаем запись при помощи actions и reducer:

image

В принципе, идея такова: мы диспетчируем actions для срабатывания reducers, которые безопасно манипулируют данными из хранилища. Таким образом, каждый компонент может безопасно считывать данные и реагировать на изменения в них.

Vuex в мире Vue эквивалентен Redux. Обе библиотеки обладают в этой сфере по-настоящему великолепной собственной поддержкой. Вместо reducers Vuex использует mutations для безопасного обновления данных хранилища. Кроме небольших отличий в именовании, обе библиотеки очень похожи. Ниже я реализовал ту же самую функциональность в приложении Vue в src/store/note.js (естественно, оба примера немного сокращены):

image

Честно говоря, Redux показалась мне полезной и мощной библиотекой-хранилищем для React, вдохновленной принципом Flux. У меня возникли проблемы из-за лишнего стереотипного кода. Естественно, теперь, когда я во всем разобрался, все кажется простым и ясным, но опыт подсказывает, что новичку в обращении с Redux будет сложно реализовать четкий и лаконичный код для React.

Например, приходится изучать и устанавливать библиотеку redux-thunk, чтобы диспетчировать действия от других действий, и для меня это был неприятный поворот. Конечно, я потратил еще пару часов, размышляя, а не воспользоваться ли redux-saga или redux-observable вместо redux-thunk. Вот тогда у меня мозги заскрипели, ощущение как раз можно описать словом thunk.

Это была сквозная тема данного проекта. Вспомните для сравнения интеграцию с Vuex – я, например, помню, как ловил себя на мысли «неужели это со мной?», налаживая все это впервые – а я к тому моменту еще даже не успел познакомиться с паттерном проектирования Flux.

Рендеринг


Из всех деталей React страньше всего мне показалась функция рендеринга. Во Vue так просто перебирать данные и изрыгать элементы, либо отображать/скрывать данные в зависимости от переменных состояния/хранилища. В React казалось довольно неестественным, что приходится создавать цикл заметок вне рендерера.

Во Vue, если вы желаете что-либо отобразить или скрыть, просто сделайте так:

image

и этот код будет зависеть от истинности вашей myVariable. В React, по-видимому, приходится сделать так:

image

Код чуть длиннее и не поддерживает так кстати пришедшейся возможности циклического перебора, которая во Vue может быть организована при помощи v-for. Но, конечно же, когда я освоился с выполнением этих маленьких простых вещичек, они перестали казаться такими странными. В общем, привыкнуть можно, просто именно так это делается в React. Но, нельзя не отметить, насколько легко во Vue устроен доступ к данным в конкретном макете страницы. Кажется, что на самом деле маленькие вспомогательные функции по душе React.

Styled-Components


Знаете, что мне больше всего нравится в этом проекте? Styled-Components. Мне по-настоящему импонирует инкапсуляция, которую они обеспечивают. Да, во Vue можно приколоть свойство scoped в разделе вашего компонента и, в принципе, сделать то же самое.

Было что-то действительно гладкое и приятное в том, как каждый компонент превращается в маленькую «вещь в себе». Возникают небольшие сложности с передачей произвольных свойств (props), но, уладив с ними некоторые детали, работать стало приятно. Помню один пользовательский комментарий, отлично ухвативший эту мысль: «приучает тебя заранее продумывать, как будешь оформлять компоненты».

Думаю, веская причина, по которой пользователь React действительно легко в это врубается – в том, что ранее оформление компонентов было устроено несколько неуклюже. Думаю, нас немного разбаловали целым миром Однофайловых Компонентов, доступных во Vue. На этом проекте я тем более смог оценить Однофайловые компоненты – поистине убийственно хорошая фича.

Сравниваем Create-React-App и Vue-CLI


Мне действительно понравилось create-react-app. Притом, какой я фанат vue-cli, вариант create-react-app – его достойный конкурент. Рекомендую всем пользователям установить экземпляр Webpack с нуля, чтобы разобраться в деталях. Но, если вам требуется что-то солидное для продакшена, настоятельно рекомендую использовать готовые инструменты скаффолдинга.

Инструменты разработки


Также отмечу: инструменты разработки в Redux и React определенно не так хороши, как инструменты Vue, это касается как оформления и цвета, так и необходимости раскрывать гигантское дерево компонентов, просто чтобы посмотреть состояние компонента. Мне в таком режиме было довольно тяжело следить за переменными приложения.

Может быть, я что-то упускаю или пользовался версией, которая сейчас не считается в сообществе действующим стандартом. Инструменты Vue кажутся мне без преувеличения потрясающими, сработанными хорошо и на совесть, а также визуально приятными. Учитывая, сколько времени придется тратить на работу с этими инструментами, вы поймете, как важны подобные мелкие детали.

Заключение


При прочих равных, я очень рад, что потратил время на изучение React. Знаю, я по-прежнему криворук и в работе с ним, и в программировании вообще, но, как минимум, теперь я освоил некоторые сложные вещи и познакомился с концепциями. Также я планирую попробовать React Native, на случай, если в будущем придется заняться разработкой мобильных приложений. Такой опыт точно не помешает.

Я мог бы бесконечно вдаваться в сравнение мелочей. На самом деле, эта статья – лишь малая толика того, что можно сказать о сравнении Vue/React. Поэкспериментируйте с приложением – мне его активно комментировали, и эти советы и подсказки пригодятся и вам.

Итог: мой следующий проект я делаю на Vue. С React управиться можно, но с виду комплектация у него чуть послабее. На первый взгляд это даже может понравиться, но, как только вы разберетесь, что к чему – сразу поймете, что пишете явно больше кода, чем на самом деле необходимо.

» Ссылка на предзаказ книги

Бумажная версия появится в конце марта.

Для Хаброжителей скидка 25% по купону — Vue.js
Издательский дом «Питер»
205,00
Компания
Поделиться публикацией

Комментарии 44

    0

    Для React аналог Vuex это не разу не Redux а скорее Mobx а точнее MobxStateTree.


    example

    mobx-state-tree


    const Todo = types
        .model({
            text: types.string,
            completed: false,
            id: types.identifierNumber
        })
        .actions(self => ({
            remove() {
                getRoot(self).removeTodo(self)
            },
            edit(text) {
                self.text = text
            },
            complete() {
                self.completed = !self.completed
            }
        }))

    Vuex


    export default new Vuex.Store({
     state: {
       text: '',
       completed: false,
       id: null,    
     },
     mutations: {
        edit(store,text) {
            store.text = text
        },
        complete(store) {
            store.completed = !store.completed
        }
     },
     actions: {
        remove({dispatch, store}){
            dispatch('todos/remove', store.id, { root: true});
        },
    });
      0
      Попробовал открыть оглавление книги, чтобы посмотреть заголовок тем, но увы:
      The requested URL /upload/contents/978544611098/978544611098_X.pdf was not found on this server.


      Можете рассказать вкратце, что по сравнению с официальным руководством будет сверх в книге? На 304 можно и воды налить, разбавив оф. гайд, а можно и достаточно интересные подробности рассказать.
        +4
        В оригинале код вставлен текстом, а вы его вставили скриншотами. Вы, блин, издеваетесь? Это же код. Банально, если хочешь прокомментировать статью — ты не можешь вставить адекватную цитату. Что за идиотская мода на скриншоты кода вместо кода?
          0
          Вот домашняя страница моего приложения. Сверху – вариант с React, снизу – с Vue:

          Сравнение каталогов с исходным кодом


          Отсутствуют иллюстрации из оригинальной статьи.
            0

            Что ж, давайте разберём роутеры. В реактовой версии смешивается роутинг и инициализация компонента. Из-за этого, если мы хотим отобразить один компонент для разных роутов, то придётся копипастить передачу всех его параметров в каждом месте использования. Обратите внимание, как автор избегает этой проблемы путём редиректа. Пользователь будет несказанно "рад" увидеть вместо формы авторизации домашнюю страницу.


            Далее, в вуешном роутере зачем-то для каждого роута указывается ещё и заголовок страницы. Зачем это роутеру? В заголовке страницы пользователь ожидает увидеть название заметки, а не абстрактный "Note". И опять же, указывается компоннет без параметров. Кастомные мета-поля — это, конечно, замечательно, но что насчёт статической типизации и подсказок IDE? Одна опечатка и проверка авторизации отваливается.


            Теперь роутинг здорового человека:


            pages() {
                return [
                    this.Menu() ,
                    ... ( this.page_id() === 'note' ) ? this.pages_note() : []
                ]
            }
            
            pages_note() {
                if( this.action_id() === 'create' ) return this.pages_note_create()
                if( this.action_id() === 'edit' ) return this.pages_note_edit()
                return [ this.Node_view() ]
            }
            
            pages_note_create() {
                return this.profile()
                ? [ this.Note_create() ]
                : [ this.Auth() ]
            }
            
            pages_note_edit() {
                return this.note().author() === this.profile()
                ? [ this.Note_edit() ]
                : [ this.Auth() ]
            }

            Так как инициализация и композиция разделены, то нам достаточно лишь указать "тут должен быть такой-то вложенный компонент". Если пользователь не авторизован или не является автором заметки, то показываем форму авторизации.

              +1
              То, что вы привели — очень похоже на God Object, но в Реакте роутинг — отвратительный, тут сомнений нет.
                0
                Где ж вы тут божественный объект углядели?
                  0
                  Сильно много ответственности. Тут и роутинг и бизнес-логика для каждого роута.
                    0
                    Роутинг — это и есть «бизнес-логика», определяющая какие экраны показывать в какой момент времени.
                      0
                      какие экраны показывать в какой момент времени.

                      Какие экраны зависимо от пути. Зависимость от других переменных — это уже не роутинг.

                      Но в вашем примере оно хоть в правильном месте лежит — в клиентской модели, а не во вьюшки, как это сделано в Реакте.
                        0
                        Не важно как это называть, суть-то одна — какие экраны показывать в зависимости от разных состояний.

                        Да нет, это вполне себе вьюшка, решающая какие вьюшки показывать внутри.
                          –1

                          Мне нравится подход, когда изменение URL лишь вызывает изменения в каком-то стейте, а роутинг — чистая функция, принимающая стейт и возвращающая готовый элемент.

                            0
                            Я вообще стараюсь абстрагировать от пути в браузере. Допустим статья у меня находится по адресу /article/123.

                            Для неё есть роут (далее псевдокод):
                            class ArticleRoute extends Route {
                              readonly template = '/article/{id}';
                            
                              constructor (readonly id: number) {}
                            }


                            Когда открывается страница браузера или меняется путь — роутер (который находится в слое модели) просчитывает, какой роут больше всего подходит. В данном случае в роутер будет присвоено что-то вроде такого:

                            router.route = new ArticleRoute(123)


                            Это, естественно, MobX-observable свойство, которое при изменении автоматически перерисует все зависимые вьюшки.

                            Ссылки на странице я указываю не как
                            <a href={`/article/${target.id}`}>
                            

                            а как
                            <Link route={new ArticleRoute(target.id)}>

                            а если надо вручную переместить пользователя куда-то, то делаю не
                            window.location = `/article/${target.id}`;
                            

                            а
                            router.move(new ArticleRoute(target.id))


                            Мне нравится абстрагированность от путей (везде кроме маппинга) и статическая типизация во всём этом. А еще, при необходимости, можно узнать текущий роут в любом компоненте без костылей, ведь он — часть стейта, как и все остальные данные.

                            А вьюшка рендерится как-то так:

                            const RouteToViewMapping = {
                              [ArticleRoute]: ArticleView,
                              // ....
                            }
                            
                            function renderRouteToView(route) {
                              const Component = RouteToViewMapping[route.constructor];
                              return <Component route={route} />;
                            }

                              0

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


                              class ArticleLink extends URL {
                                  constructor( readonly id : string ) {
                                      super( `/article/${id}` , document.location )
                                  }
                              }

                              А вот именно роутинг у вас спрятан в RouteToViewMapping.

                                0
                                А вот именно роутинг у вас спрятан в RouteToViewMapping.


                                Э не, роутинг у меня спрятан в роутере, который определяет, какой именно Роут сейчас активен. То есть `router.route`.

                                Роутер на вход получает URL страницы и решает, какой Роут подходит под этот урл. Если заменить на то, что вы предложили — темплейт будет съеден.

                                А вот именно роутинг у вас спрятан в RouteToViewMapping.
                                А тут у меня описано, как каждый из роутеров нужно рендерить. Соответственно и тесты, к примеру пишутся так:

                                1. Проверяем, что Роутер правильно роутит
                                2. Проверяем, что Вьюшка правильно рендерит текущий роут.

                      0
                      На каждый роут в приложении — свой метод одного и того же объекта. При 30 роутах у объекта будет 30 методов?
                      Если уж начали про роутинг здорового человека писать, то укажу, пожалуй universal-router.
                        0
                        Если у вас на одном уровне иерархии 30 вариантов вложенных компонент, то будет 30 методов, да.
                  +3
                  Сразу видно человек не пишет на реакте и сравнивает с ним свой любимый vue

                  На счет реакт-роутера есть очень логичное решение.
                  делаете HOC, который инкапсулирует в себя всю логику с проверками на авторизацию, ACL и т.д.

                  А потом очень просто это все подключаем
                      <Route path="/" exact component={PostList} />
                      <Route path="/edit/:id" component={WithACL(PostEdit, {allow=['admin', 'author']})}  />
                      <Route path="/delete/:id" component={WithACL(PostDelete, {allow=['admin']})}  />
                      <Route path="/create/" component={WithACL(PostCreate, {allow=['author']})} />
                  


                  при этом вместо редиректа, мы можем спокойно показать форму логина на приватном роуте
                    +1
                    > Сразу видно человек не пишет на реакте и сравнивает с ним свой любимый vue

                    Тут даже хуже, человек не владеет жаваскриптом, тк для композиции в реакте не нужно изучать реакт.
                      0
                      Давно не работал с реакт роутером, но вместо HOC
                      <Route path="/edit/:id" component={WithACL(PostEdit, {allow=['admin', 'author']})}  />
                      

                      своя обертка над Route, на мой взгляд, будет немного получше:
                      <CustomRoute path="/edit/:id" component={PostEdit} allow={['admin', 'author'])}  />


                        0
                        А как два HOC'а замените? Это ведь классические композиция-против-наследования.
                          +1
                          Я имел ввиду не наследование CustomRoute от Route, а рендерить Route внутри CustomRoute.
                          Сейчас понял, что фактически предложил HOC, но для Route, а не для PostEdit.
                      0
                      А мне, чем Vue больше нравится, так это Enter/Leave & List Transitions. Очень удобно работать с простыми анимациями. В реакт сложнее.
                        –1

                        Может я что не понял — человек ограничения доступа неавторизованным пользователям реализует на фронте? Серьезно?

                          +2
                          Ну это нормально. Надо выдать вменяемую страницу, а не просто админский шаблон с незагруженными из-за 403 данными. Просто на сервере это тоже реализуется
                            0
                            Есть мнение, что такой шаблон надо показывать не в зависимости от роутов, а если от сервера пришёл 403 ответ. Тогда логика проверки прав будет в одном месте, а не размазана между фронтом и бэком, с периодическим разъездами то в одну, то в другую сторону.
                              +1
                              В теории оно то, конечно, так, но на практике оно так не получается. Все-равно на клиенте надо делать пре-валидацию для более удобной работы. Да и банально зачем делать запрос и ждать ответ, если клиент и сам может знать, что этого делать нет необходимости.

                              Другой пример — валидация полей форм, которую нужно делать на сервере и можно сделать исключительно там, но от этого страдает ux.
                                –1
                                Да и банально зачем делать запрос и ждать ответ, если клиент и сам может знать, что этого делать нет необходимости.
                                Single source of truth. Если проверка существует, то ее логику лучше реализвать один раз. Если хочется переиспользовать, то автотматически сконвертировать в JS для веба, но не писать саму логику 2 раза, можно ведь ошибки сделать, расхождения и тд. Поэтому валидация на сервере, а фронт просто отражает результат валидации.
                                  +1
                                  Если проверка существует, то ее логику лучше реализвать один раз
                                  Кому лучше? Явно не пользователям

                                  то автотматически сконвертировать в JS для веба
                                  Иногда это и правда лучше, но не всегда возможно, увы. Иногда банально писать инструменты для этого дороже, чем сделать вручную.

                                  можно ведь ошибки сделать, расхождения и тд
                                  Можно сделать, а можно и не сделать.

                                  Я предпочитаю не слать на сервер запросов, которые можно не послать. И вообще — лишняя интеграция между двумя компонентами очень часто приводит к дополнительному усложнению, которое тоже является источником ошибок.
                                    –1
                                    Наверное, при авторизации на сервере можно получить с него список доступных областей сайта, и потом уже обрабатывать этот список на фронте — пущать или не пущать клиента. Тогда лишних запросов не будет, а на случай расхождений 403 тоже можно обработать.
                                      0
                                      Мне кажется, что большинство серверов потребует серьезной переработки, чтобы предоставить такой EndPoint. Много вы знаете фреймворков типа JS Express, Ruby on Rails, Django, где есть заточенный под это функционал? Как он реализован?
                                        0
                                        Не постесняюсь заявить, что я ничего из перечисленного вами не знаю, кроме названий, дел с ними не имел. Увы.
                                        Но чисто умозрительно, ведь каждый пользователь в процедуре авторизации получает роль — потенциальный клиент, активный клиент, сотрудник, менеджер, поддержка и т.п. Роли можно сопоставить список доступных областей сайта, этот список отдавать отдельным рестом в json. Наверное, в роутинге на фронте будет несложно проверить, есть ли область, в которую делается попытка перехода, в этом списке?
                                        Естественно, такой список может быть только по крупному. Например, ЛК недоступен никому, кроме клиента. Список заказов доступен клиенту и сотрудникам, однако переход на страницу заказа, не принадлежащего клиенту, вернёт 403. Хотя сама область списка заказов клиенту разрешена.
                                          0
                                          Я верю, что это возможно, мне интересно, есть ли уже где-то готовые реализации.
                                            0
                                            Я не в курсе
                                              0

                                              Вроде все современные фреймворки (вернее их роутеры) умеют показывать условные 401 или 403 страницы при попытках перейти на те роуты, которые текущему пользователю недоступны. "ручками" только написать функцию проверки доступности для роута типа (): boolean => authStore.user.roles.contains(Roles.admin)

                                                0
                                                Та 401 — это просто. Я о том, можно ли одним запросом получить всю мапу вида { EndPoint: [Roles] }, чтобы запустить идею sshmakov
                                  –1
                                  Скажите, а есть ли какие-то преимущества «клиентского роутинга» кроме псевдо-улучшенного UX? Мне привычнее когда смена роута вызывает нативную перезагрузку страницы, это как-то заложено на подсознании в моём пользовательском опыте и ничего страшного в этом не вижу. И в то же время наоборот, когда я нажимаю браузерную кнопку «назад» — ожидаю что будет перезагрузка и я конкретно выйду из данного приложения, но испытываю «конфьюзинг» когда вместо этого просто меняется экран внутри приложения. По идее, если сценарий в spa-приложении предусматривает возврат на один экран назад, то такая кнопка должна быть в самом дизайне приложения (и роутинга не нужно).
                                  Может есть какие-то преимущества в плане разработки? Просто в моём небольшом опыте, проще чтоб роутинг был серверный («нативный» если угодно, а не клиентский-костыльный). На беке разруливаются и права, и сборку бандлов в webpaсke удобнее настраивать, без всякого code-splitting и tree-shaking (эти понятия путаю, если что..))
                                  Т.е каждая страница — это отдельное мини-SPA со своим бандлом (не толстым, а только с тем, что нужно для этой страницы).
                                  У нас проект на symfony. Сайт использует серверный роутинг. При этом в рамках этого сайта два абсолютно разных личных кабинета — и это два отдельных SPA со своим отдельными роутами. Бонусы — не толстые бандлы, хорошее переиспользование кода, удовлетворённые seo-шники и поисковики.
                                  Так вот, ввиду небольшого опыта, очень интересно зачем используют впринципе клиентский роутинг? Интересуют конкретные кейсы когда он может быть оправдан. Заранее спасибо.
                                    +1

                                    А я вот испытываю "конфьюзинг" когда "гуляю" по личному кабинету, нажимаю "назад" в браузере и вместо предыдущего экрана вижу главную страницу или вообще форму логина. Также его испытываю, когда жму "продублировать вкладку" и вижу совсем другой экран. Одно большое SPA или несколько мини-SPA — не принципиально, но если нет полноценного клиентского роутинга, то лично мне сложно применить к ним термин "SPA" в современном его понимании.

                                      0
                                      SPA бывает и без таких недостатков. Попробуйте походить в пределах сайта — один раз загружаем ~400kb кода и потом получаем крайне отзывчивый сайт без всяких перезагрузок и лишних запросов, который будет работать даже если вырубить интернет. Мне кажется это очень удобным, значительно более удобным, чем каждый раз скачивать с нуля страницу.
                                        +1
                                        Ну так это выглядит как полноценный SPA с клиентским роутингом корректно, в том числе, обрабатывающим навигацию. Выше я говорил про «недоSPA», когда вроде SPA, но как решишь использовать кнопки навигации, обновить страницу или поделиться ссылкой, то получаешь нечто невразумительное.

                                        Уж лучше, как по мне грузить страницы полноценно, чем делать «недоSPA».
                                          0
                                          Ну можно сделать и обычный сайт, на котором не будет работать навигация. Сделать через пост-запросы вместо гет-запросов к примеру.
                                        0
                                        Заголовок спойлера
                                        О, Вова, привет!
                                        Ярослав, с прошлой работы)


                                        SPA — сингл пейдж, думаю не просто так названо.

                                        Ок. Если делать клиентский роутинг, то кто решает какие именно состояния приложения соответствуют каким именно урл-ам? Неужто дизайнер?))

                                        Что в ПРИЛОЖЕНИИ должно заставить нажать браузерную кнопку «назад»?
                                        В моём понимание SPA-приложение, это именно приложение, инструмент, сервис, дашборд, личный кабинет, etc. То, чем не принято делится по ссылке. Например, некий онлайн фотошоп, онлайн эксель-таблицы и т.д. Там куча компонентов и куча состояний этих компонентов. Я нажимаю «назад»… как решить какой компонент откатывать назад?

                                        Наверное, проблема, которую я надумал, чуть шире. Неправильное разделение где нужно spa, а где нужно по старинке — на серверных шаблонах. И когда делают контентный сайт как приложение, то конечно нужен клиентский роутинг. А потом и SSR скоро попросят.

                                        Помнится, в начале появления React-а, они так себя и позиционировали, что мол… мы не фреймворк, нас можно внедрять постепенно, т.е. выделили на какой-то странице враппер, и внутри него делайте мини-spa. Хороший способ избавится от легаси jqwery лапши. При этом роутинг? какой роутинг? не слышали)

                                        П.С.
                                        При дублировании вкладки — откроется начальное состояние приложения. Это я считаю адекватным поведением.

                                        Поэтому вначале спросил, какие реальные примеры использования клиентского роутинга? Не считая контентных сайтов, которые почему-то сделаны на ангуляре, допустим..))
                                          +1
                                          Привет :)

                                          Именно дизайнер, UX-дизайнер :) А заставляет нажать две вещи: желание вернуть приложение назад, на предыдущий экран или шаг какого-то визарда ;) и наличие кнопки «назад» в UI, в том числе аппаратных или почти аппаратных в девайсах типа смартфонов и штатных в браузерах.

                                          И, да, не во всех типах приложений оно такое нужно, по крайней мере на каждый чих: «назад» — не аналог «отменить изменения», это «вернуться туда где только что был, если это возможно».
                                +2
                                Похоже ph_piter начитает гонку с ru_vds в том кто больше наклепает переводов.

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое