Skip to content

Instantly share code, notes, and snippets.

@zmts
Last active March 17, 2021 14:43
Show Gist options
  • Select an option

  • Save zmts/b91f2311048749b9cdef78553f18d608 to your computer and use it in GitHub Desktop.

Select an option

Save zmts/b91f2311048749b9cdef78553f18d608 to your computer and use it in GitHub Desktop.
Про состояние компонентов Vue.js и где его держать.

FLUX vs noFLUX in Vue.js

Жил был разработчик. Писал он себе кодяру на Vue.js и горя не знал, пока черти не дернули его более внимательно прочитать доку по VUEX. И увидел он там волшебное слово FLUX.

Про состояние компонентов Vue.js и где его держать.

Обычно при разработке приложений придерживаюсь принципа:

  • Все данные которые относятся непосредственно компоненту храним непосредственно в нем
  • Global/Shared данные в стор
  • Как вариант разделать stateless и stateful компоненты

На пример у нас есть простенькая страничка со списком айтемов и нам необходимо его отрисовать. Я создаю компонент pages\news\NewsPage.vue и pages\news\NewsItem.vue.

В первом обращаюсь к АПИ, сохраняю список айтомов, меняю статусы(loading/error). Все в одном компоненте(файле). Второй принимает через проп айтем и отрисовывает его. Все! Далее для дебага юзаем как обычно VueDevTools и не знаем горя.

Но у FLUX'а на эту задачу немного другой ответ. И так рассмотрим тот же пример с двумя компонентами. Для реализации данного ф-ционала нам понадобится взаимодействовать с пятью абстракциями:

  • State module store
  • Action
  • API call
  • Mutation
  • Getter

В action через api call фетчим данные >> записываем данные в стор через mutation. При этом зачастую для каждой сущности(доменной группы сущностей) в сторе создается отдельный модуль и в каждом модуле лежит 4-5 js файлов (actions.js, mutations.js ...).

Для фетча данных выходит такой путь DISPATCH >> ACTION >> API_CALL >> MUTATION >> GETTER. Для отображение какого нибудь loading статуса, необходимо пройти$store >> someModuleState >> loading ну да или воспользоваться вспомогательной ф-цией mapState. Вместо this.loading. А как быть с формочками тоже прикажите хранить эти все чекбоксы/инпуты в сторе ?

При таком раскладе каждый разработчик трактует по своему как разделять данные. Это в стор/это в локальное состояние компонента. У каждого свой FLUX.

А все это делается что бы придерживаться принципа одностороннего изменения данных. Компонент не должен знать как менять данные итд. Что в итоге деет свои плюшки при поддержке и дебаге приложения. А если сюда еще добавить еще и функциональщину и иммутабельность... все ховайся... А по факту в большинстве случаев(я не обобщаю.) все как дебажили консоллогом так и дебажат. Периодически заглядывая в VueDevTools.

Внимание вопрос!

В контексте React приложений своя атмосфера и оно там к месту.

  • К месту ли такие танцы в контексте Vue ?
  • Стоит ли овчинка выделки ?
  • Как понимать что хранить в сторе а что в локальном состоянии компонента ? Статусы (error/loading), филды формочек, чекбоксы... это все куда ?

Если вам есть что сказать буду рад обсудить в комментах.

p.s.

@igogrek
Copy link

igogrek commented Sep 10, 2018

Практически полностью согласен с @xanf, поэтому не буду вдаваться в подробности, а просто приведу наш опыт и несколько примеров.

Мы сделали пару проектов используя"чистый" store с попыткой выносить туда все данные, как только они появляются. То есть не использовать локальную data вовсе, дабы потом сэкономить время на перенос из data в store. В конечном итоге, вся эта красивость и чистота кода большой пользы нам не принесла, а размер стора вырос весьма существенно.
Особенно плохо это работало для случаев когда данные как раз зависят от жизненного цикла компонента. С локальной датой хуки прекрасно очищают ее в момент уничтожения компонента, а со стором это вовсе не так удобно.

В итоге для себя мы выбрали смешанный подход:

  1. data используется всегда по умолчанию до тех пор пока необходимо использовать одни и те же данные в 2+ компонентах/страницах.
    Принципиально не используем в таких случаях передачу данных через props ниже по дереву компонентов.
  2. Только data всегда используется в простых переиспользуемых компонентах, вроде чекбоксов, селектов, таблиц и т.д.,
    • за исключением случаев, когда компоненты состоят из большого количества подкомпонентов (когда они подпадают под пункт 1), тогда у корневого компонента появляется свой собственный стор
  3. Всегда используем геттеры для обращения к полям стора
  4. Используем ACTION'ы только если это асинхронные операции или комбинации большого количества мутаций, а так же в случае если необходимо одну операцию выполнять из 2+ компонентов

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment