В Vuex, какова логика наличия как «действий», так и «мутаций»?
Я понимаю логику компонентов, не способных изменять состояние (что кажется разумным), но наличие как действий, так и мутаций похоже на то, что вы пишете одну функцию для запуска другой функции, чтобы затем изменить состояние.
В чем разница между «действиями» и «мутациями», как они работают вместе, и более того, мне любопытно, почему разработчики Vuex решили сделать это таким образом?
mutations
иactions
определены в документации vuex как методы изменения состояния. Вам не нужно действие, чтобы совершить мутацию.Ответы:
Вопрос 1 : Почему разработчики Vuejs решили сделать это таким образом?
Ответ:
Вопрос 2 : В чем разница между «действием» и «мутацией»?
Давайте сначала посмотрим официальное объяснение:
Вот мое объяснение вышесказанного:
источник
Мутации синхронны, тогда как действия могут быть асинхронными.
Иными словами, вам не нужны действия, если ваши операции синхронны, в противном случае реализуйте их.
источник
Я считаю, что понимание мотиваций, стоящих за мутациями и действиями, позволяет лучше судить о том, когда использовать, что и как. Это также освобождает программиста от бремени неопределенности в ситуациях, когда «правила» становятся нечеткими. Немного рассуждая об их соответствующих целях, я пришел к выводу, что, хотя могут определенно быть неправильные способы использования действий и мутаций, я не думаю, что существует канонический подход.
Давайте сначала попробуем понять, почему мы даже проходим либо Мутации, либо Действия.
Строго говоря, вы можете изменить
state
непосредственно из ваших компонентов. Этоstate
просто объект JavaScript, и нет ничего волшебного, что могло бы отменить изменения, которые вы внесли в него.Однако, делая это, вы разбрасываете мутации своего состояния повсюду. Вы теряете возможность просто открыть единственный модуль, в котором находится состояние, и сразу увидеть, какие операции могут быть применены к нему. Централизованные мутации решают это, хотя и за счет некоторого шаблона.
Я думаю, что если вы замените что-то короткое на шаблон, вы захотите, чтобы шаблон также был маленьким. Поэтому я предполагаю, что мутации должны быть очень тонкими обертками вокруг нативных операций над состоянием, почти без бизнес-логики. Другими словами, мутации предназначены для использования в основном как сеттеры.
Теперь, когда вы централизовали свои мутации, у вас есть лучший обзор изменений вашего состояния, и поскольку ваш инструмент (vue-devtools) также знает об этом месте, это облегчает отладку. Также стоит помнить, что многие плагины Vuex не отслеживают состояние напрямую, чтобы отслеживать изменения, а скорее полагаются на мутации. Таким образом, изменения состояния невидимы для них.
Действия, такие как мутации, также находятся в модуле магазина и могут получать
state
объект. Что подразумевает, что они могут также изменить его напрямую. Так какой смысл иметь оба? Если мы рассуждаем о том, что мутации должны быть небольшими и простыми, это означает, что нам нужны альтернативные средства для размещения более сложной бизнес-логики. Действия являются средством для этого. И поскольку, как мы установили ранее, vue-devtools и плагины знают об изменениях посредством мутаций, чтобы оставаться последовательными, мы должны продолжать использовать мутации из наших действий. Кроме того, поскольку все действия должны охватывать все объекты, а логика, которую они инкапсулируют, может быть асинхронной, имеет смысл, что действия с самого начала просто делались бы асинхронными.Часто подчеркивается, что действия могут быть асинхронными, а мутации - нет. Вы можете решить рассматривать различие как указание на то, что мутации должны использоваться для чего-то синхронного (и действия для чего-либо асинхронного); тем не менее, вы столкнетесь с некоторыми трудностями, если, например, вам нужно будет зафиксировать более одной мутации (синхронно) или вам нужно работать с геттером из ваших мутаций, поскольку функции мутации не получают ни геттеры, ни мутации в качестве аргументов ...
... что приводит к интересному вопросу.
Я еще не нашел удовлетворительного ответа на этот вопрос. Я видел некоторые объяснения со стороны основной команды, что я нашел спор в лучшем случае. Если я резюмирую их использование, то получатели должны быть вычислены (и часто кэшированы) расширениями состояния. Другими словами, они в основном все еще находятся в состоянии, хотя и требуют предварительных вычислений и обычно доступны только для чтения. По крайней мере, так их поощряют.
Таким образом, предотвращение прямого доступа мутаций к геттерам означает, что теперь необходима одна из трех вещей, если нам необходимо получить доступ от первого к некоторым функциональным возможностям, предлагаемым последним: (1) либо вычисления состояний, предоставляемые геттером, дублируются где-то, что доступно в Мутацию (неприятный запах), или (2) вычисленное значение (или соответствующий сам Геттер) передается в качестве явного аргумента Мутации (фанки), или (3) сама логика Геттера дублируется непосредственно в Мутации без дополнительного преимущества кэширования, предоставляемого Getter (stench).
Ниже приведен пример (2), который в большинстве сценариев, с которыми я столкнулся, кажется «наименее плохим» вариантом.
На мой взгляд, вышесказанное кажется не только немного запутанным, но и несколько «утечкой», поскольку часть кода, присутствующего в Action, явно вытекает из внутренней логики Mutation.
На мой взгляд, это показатель компромисса. Я считаю, что разрешение мутациям автоматически получать геттеров сопряжено с некоторыми трудностями. Это может быть либо дизайн самого Vuex, либо инструментарий (vue-devtools et al), либо сохранение некоторой обратной совместимости, либо некоторая комбинация всех заявленных возможностей.
Я не верю в то, что передача Геттеров своим Мутациям сама по себе является признаком того, что вы делаете что-то не так. Я считаю это просто «исправлением» одного из недостатков фреймворка.
источник
computed
выходной. Они только для чтения. Более хорошим способом просмотра мутаций может быть удаление того,if else
что у вас есть. Документы Vuex говорят, что вы можете разместить более 1commit
внутри действия. Поэтому было бы логично предположить, что вы можете совершить определенную мутацию в зависимости от логики. Я рассматриваю действия как способ диктовать, какую мутацию запустить.Я думаю, что ответ TLDR заключается в том, что мутации должны быть синхронными / транзакционными. Поэтому, если вам нужно выполнить Ajax-вызов или выполнить любой другой асинхронный код, вы должны сделать это в Action, а затем зафиксировать мутацию после, чтобы установить новое состояние.
источник
Основные различия между действиями и мутациями:
источник
Согласно
docs
Действия похожи на мутации , различия в том, что:
Рассмотрим следующий фрагмент.
источник
Отказ от ответственности - я только начал использовать vuejs, так что это только я экстраполировал замысел проекта.
Отладка машины времени использует снимки состояния и показывает график действий и мутаций. В теории у нас могла бы быть только
actions
запись о методах установки и получения состояний, чтобы синхронно описывать мутацию. Но потом:mutations
транзакциями, но тогда мы можем сказать, что транзакция должна быть улучшена, в отличие от того, чтобы быть гоночным условием в действиях. Анонимные мутации внутри действия могли бы легче выявлять подобные ошибки, потому что асинхронное программирование хрупко и сложно.Сравните следующий журнал транзакций с именованными мутациями.
С журналом транзакций, который не имеет именованных мутаций:
Я надеюсь, что вы можете извлечь из этого примера потенциальную дополнительную сложность в асинхронной и анонимной мутации внутри действий.
https://vuex.vuejs.org/en/mutations.html
источник
Мутации:
Действия:
В Redux Way
Почему оба?
Когда приложение будет расти, кодирование и количество строк будут увеличиваться. В этот раз вы должны обрабатывать логику в действиях, а не в мутациях, потому что мутации являются единственным полномочием для изменения состояния, оно должно быть максимально чистым.
источник
Это тоже смутило меня, поэтому я сделал простую демонстрацию.
component.vue
store.js
Изучив это, я пришел к выводу, что мутации - это соглашение, направленное только на изменение данных для лучшего разделения проблем и улучшения ведения журнала до и после обновленных данных. Принимая во внимание, что действия являются уровнем абстракции, который обрабатывает логику более высокого уровня и затем вызывает мутации соответственно
источник
1. Из документов :
Действия могут содержать асинхронные операции, но мутация не может.
2. Мы вызываем мутацию, мы можем изменить состояние напрямую. и мы также можем изменить действие следующим образом:
Действия предназначены для обработки большего количества других вещей, мы можем сделать там много вещей (мы можем использовать асинхронные операции), а затем изменить состояние, отправив туда мутацию.
источник
Потому что без мутаций нет государства! Когда зафиксировано - выполняется часть логики, которая изменяет состояние в предсказуемой форме. Мутации - это единственный способ установить или изменить состояние (так что прямых изменений нет!), И более того - они должны быть синхронными. Это решение обеспечивает очень важную функциональность: мутации входят в devtools. И это обеспечивает отличную читаемость и предсказуемость!
Еще одна вещь - действия. Как уже было сказано - действия совершают мутации. Таким образом, они не меняют магазин, и нет необходимости, чтобы они были синхронными. Но они могут управлять дополнительной частью асинхронной логики!
источник
Может показаться ненужным иметь дополнительный слой
actions
для вызоваmutations
, например:Так что, если вы звоните
actions
звонкиlogout
, почему бы не назвать саму мутацию?Вся идея действия заключается в том, чтобы вызвать несколько мутаций изнутри одного действия или сделать Ajax-запрос или любую другую асинхронную логику, которую вы можете себе представить.
Мы можем в конечном итоге иметь действия, которые делают несколько сетевых запросов и в конечном итоге вызывают много разных мутаций.
Поэтому мы стараемся наполнить как можно больше сложностей от
Vuex.Store()
нашихactions
, и это оставляет нашmutations
,state
иgetters
чище и прямолинейным и падает в соответствии с типом модульности , что делает библиотеки , как Vue и React популярны.источник
Я профессионально использую Vuex около 3 лет, и вот, как мне кажется, я выяснил о существенных различиях между действиями и мутациями, о том, как вы можете извлечь пользу из их совместного использования, и как вы можете сделать свою жизнь тяжелее, если вы не используйте это хорошо.
Основная цель Vuex - предложить новый шаблон для управления поведением вашего приложения: Реактивность. Идея состоит в том, чтобы переложить оркестровку состояния вашего приложения на специализированный объект: магазин. Он удобно предоставляет методы для подключения ваших компонентов непосредственно к данным вашего магазина, которые будут использоваться по своему усмотрению. Это позволяет вашим компонентам сосредоточиться на своей работе: определить шаблон, стиль и базовое поведение компонента для представления вашему пользователю. Между тем, магазин справляется с большой загрузкой данных.
Это не единственное преимущество этого паттерна. Тот факт, что хранилища являются единым источником данных для всего вашего приложения, дает большой потенциал повторного использования этих данных во многих компонентах. Это не первый шаблон, который пытается решить эту проблему межкомпонентного взаимодействия, но его преимущество состоит в том, что он заставляет вас реализовать очень безопасное поведение для вашего приложения, в основном запрещая вашим компонентам изменять состояние этих общих данных. и вместо этого заставьте его использовать «публичные конечные точки» для запроса изменений.
Основная идея заключается в следующем:
Это сказанное, волшебство начинается, когда мы начинаем проектировать наше приложение таким способом. Например:
В конце концов, у нас есть пользовательский опыт, который считается «реактивным». С точки зрения нашего пользователя, элемент был удален немедленно. В большинстве случаев мы ожидаем, что наши конечные точки будут просто работать, так что это идеально. Когда это терпит неудачу, у нас все еще есть некоторый контроль над тем, как наше приложение будет реагировать , потому что мы успешно отделили заботу о состоянии нашего интерфейсного приложения от реальных данных.
Помните, вам не всегда нужен магазин. Если вы обнаружите, что пишете магазины, которые выглядят так:
Мне кажется, что вы используете хранилище только в качестве хранилища данных и, возможно, упускаете из виду его реактивность, не позволяя ему также контролировать переменные, на которые реагирует ваше приложение. По сути, вы можете и должны выгрузить некоторые строки кода, написанные в ваших компонентах, в свои магазины.
источник