Как правильно изменять данные в массиве
Есть данные с сервера в виде объекта, там есть поле created_at которое приходит в формате '2021.05.21 16.44.00', мне нужно это поле вывести в компоненте в виде записи 21 мая 2021 г. и 10дней назад. Вопрос где мне нужно изменять это поле, использую vuex. Массив перебираю в компоненте для вывода новостей. В данный момент я изменяю это поле непосредственно в компонентах в местах вывода даты, но мне кажется это неправильный подход.
Ответы (1 шт):
Изменять данные, получаемые в Vuex из асинхронных источников, следует в действиях (Actions).
То есть, следуя принципу разделения ответственности - преобразование дат разумнее выполнять
либо в том же самом действии, которое читает данные с этими датами из внешнего источника;
либо в отдельном действии, вызываемом из других действий/компонентов, если одно и тоже преобразование дат требуется в нескольких местах (применяя с осторожностью, не допуская лишних перевычислений).
Выполнять такое преобразование в компонентах - не следует, по той причине, что это приводит к лишним повторным вычислениям и "рассинхронизации" представлений.
Технически, данные можно преобразовывать и в мутациях (Mutations), но рекомендуется делать мутации максимально простыми, ограниченными только логикой присваивания свойствам объекта состояния (State).
К сожалению, эта рекомендация указана в оф. документации довольно расплывчато:
a) «Instead of mutating the state, actions commit mutations»
b) «Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications»
, и читателю требуется "сложить 2 и 2" для того чтобы прийти к логическому выводу об архитектурной роли мутаций... Этот вывод, на самом деле, звучит весьма часто и в разных вариациях, поэтому здесь я приведу только один ближайший пример - «mutation doesn't care about business logic, it just cares about "state"».
Конечно, из любого простого правила есть исключения.
Тут исключением является тот случай, когда ожидается что одни и те же данные должны иметь разное представление в разных компонентах, и таких компонентов предполагается множество. В таком случае, используются геттеры (Getters) для получения данных состояния в трансформированном виде.
Почему - потому что результаты геттеров в нефункциональном формате, кэшируются аналогично вычисляемым (computed) полям экземпляра Vue: возвращаемые значения обновляются только при обновлении связанных полей состояния.
Например, если несколько компонентов выводят даты в формате '12 июня 2021г.', а другие несколько компонентов в формате '2 дня назад' (форматы вывода не имеют значения, значимо их различие) - лучше записывать в стейт даты в виде экземпляров родного типа Date или в unixtime, а окончательные выводимые строки генерировать уже в геттерах.
Очевидно, что такое решение является всего лишь более централизованным и более шустрым аналогом дублирования одинаковых computed свойств в каждом компоненте.