Vuex Action проти мутацій


173

У Vuex, яка логіка мати і "дії", і "мутації?"

Я розумію логіку компонентів, які не в змозі змінювати стан (що здається розумним), але маючи і дії, і мутації, схоже, ви пишете одну функцію, щоб запустити іншу функцію, щоб потім змінити стан.

Яка різниця між "діями" та "мутаціями", як вони працюють разом, і більше того, мені цікаво, чому розробники Vuex вирішили зробити це саме так?


2
Дивіться "Про дії", я думаю: vuex.vuejs.org/en/mutations.html#on-to-action
Roy J

пов'язана дискусія: github.com/vuejs/vuex/isissue/587
chuck911

1
Ви не можете безпосередньо вимкнути стан магазину. Єдиний спосіб змінити стан магазину - явно здійснюючи мутації. Для цього нам потрібні дії для здійснення мутацій.
Суреш Сапкота

1
@SureshSapkota це твердження дуже заплутане, оскільки обидва mutationsі actionsвизначаються в документації vuex як методи зміни стану. Вам не потрібні дії, щоб здійснити мутацію.
Грем

1
Мутації, як випливає з назви, використовуються для модифікації / мутації об'єкта стану. Дії досить схожі на мутації, але замість того, щоб мутувати стан, дії здійснюють мутації. Дії можуть містити будь-який довільний асинхронний код або логіку бізнесу . Vuex рекомендує об'єкт стану мутувати лише у функціях Mutation. Також рекомендується не запускати будь-який важкий або блокуючий код всередині функцій Mutation, оскільки він є синхронним за своєю суттю .
Еммануель Нені

Відповіді:


221

Питання 1 : Чому розробники Vuejs вирішили зробити це саме так?

Відповідь:

  1. Коли ваша заявка стане великою, і коли над цим проектом працюють декілька розробників, ви виявите, що "управління державою" (особливо "глобальна держава") буде ускладнюватися.
  2. Шлях vuex (як і Redux в react.js ) пропонує новий механізм управління станом, збереженням стану та "збереженням та відстеженням" (це означає, що кожну дію, яка змінює стан, можна відслідковувати інструментом налагодження: vue-devtools )

Питання 2 : Яка різниця між "дією" та "мутацією"?

Розглянемо спочатку офіційне пояснення:

Мутації:

Мутації Vuex - це по суті події: кожна мутація має ім'я та обробник.

import Vuex from 'vuex'

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    INCREMENT (state) {
      // mutate state
      state.count++
    }
  }
})

Дії: Дії - це лише функції, що розсилають мутації.

// the simplest action
function increment (store) {
  store.dispatch('INCREMENT')
}

// a action with additional arguments
// with ES2015 argument destructuring
function incrementBy ({ dispatch }, amount) {
  dispatch('INCREMENT', amount)
}

Ось моє пояснення до сказаного:

  • мутація - єдиний спосіб зміни стану
  • мутація не стосується бізнес-логіки, вона просто дбає про "стан"
  • дія - ділова логіка
  • дія може відправляти більше 1 мутації одночасно, вона просто реалізує ділову логіку, вона не переймається зміною даних (якими керує мутація)

80
Корисний факт, що дія "є діловою логікою" і може відправляти кілька мутацій одночасно. Це відповідь, яку я шукав. Дякую.
Кобі

11
Ви, прихильники, говорите, що "відправляєте мутацію". Чи не є правильним формулюванням того, що ви ЗНАЙДАЄТЕ мутацію?
Проблеми

4
Ви відправляєте дії та здійснюєте мутації.
eirik

4
відправка вже не працює в vue 2.0 для мутації, вам потрібно зробити мутацію в дії.
SKLTFZ

18
@Kaicui У цій відповіді відсутня примітка про те, що мутації завжди синхронізовані та дії, які потенційно можуть бути асинхронними. Крім цього, хороша відповідь!
декати

58

Мутації синхронні, тоді як дії можуть бути асинхронними.

Інакше кажучи: вам не потрібні дії, якщо ваші операції синхронні, інакше реалізуйте їх.


2
це насправді відповідає на питання, яке я збирався поставити, про те, як приклад todomvc не використовує дій.
sksallaj

7
«Вам не потрібно дію , якщо ваші дії є синхронними» : Це не так: ви робите потреба дію , якщо ви хочете створювати множинні мутації з одного модуля, тому що ви не можете викликати деякі інші дії від дії.
Раймундус

1
Очевидним продовженням цієї відповіді було б "тоді, чому б не просто зробити дії та позбутися мутацій"
Michael Mrozek

34

Я вважаю, що розуміння мотивацій, що стоять за мутаціями та діями, дозволяє краще судити, коли використовувати, як і як. Це також звільняє програміста від тягаря невизначеності в ситуаціях, коли "правила" стають нечіткими. Трохи обміркувавши їхні цілі, я прийшов до висновку, що хоча напевно можуть бути неправильні способи використання дій та мутацій, я не думаю, що існує канонічний підхід.

Спершу спробуємо зрозуміти, чому ми навіть переживаємо або мутації, або дії.

Навіщо в першу чергу проходити через котельну плиту? Чому б не змінити стан безпосередньо в компонентах?

Строго кажучи, ви можете змінити stateбезпосередньо свої компоненти. Це stateпросто об’єкт JavaScript, і немає нічого магічного, що поверне зміни, які ви внесете до нього.

// Yes, you can!
this.$store.state['products'].push(product)

Однак, роблячи це, ви розпорошуєте свої мутації стану по всьому світу. Ви втрачаєте можливість просто відкрити один модуль, в якому знаходиться стан, і з першого погляду побачите, які операції можна застосувати до нього. Централізовані мутації вирішують це, хоча і ціною деяких котлових плит.

// so we go from this
this.$store.state['products'].push(product)

// to this
this.$store.commit('addProduct', {product})

...
// and in store
addProduct(state, {product}){
    state.products.push(product)
}
...

Я думаю, що якщо ви заміните щось коротке на котельну, ви хочете, щоб і котла мала. Тому я припускаю, що мутації мають бути дуже тонкими обгортками навколо власних операцій над державою, майже не мають ділової логіки. Іншими словами, мутації мають використовуватися в основному як сетери.

Тепер, коли ви централізували свої мутації, ви маєте кращий огляд змін у своєму стані, і оскільки ваш інструментарій (vue-devtools) також знає про це місце, це робить налагодження простішим. Варто також пам’ятати, що багато плагінів Vuex не стежать за станом безпосередньо, щоб відстежувати зміни, вони швидше покладаються на мутації. Таким чином, "поза межами" зміни стану невідомі.

Отже mutations, у actionsчому різниця?

Дії, як і мутації, також знаходяться в модулі магазину і можуть приймати stateоб’єкт. Що означає, що вони також могли його безпосередньо мутувати. Тож який сенс мати обоє? Якщо ми вважаємо, що мутації мають бути малі та прості, то це означає, що нам потрібен альтернативний засіб для більш детальної бізнес-логіки. Дії - це засіб для цього. А оскільки, як ми встановили раніше, vue-devtools та плагіни знають про зміни через мутації, щоб залишатися послідовними, нам слід продовжувати використовувати мутації в наших діях. Крім того, оскільки дії маються на увазі, що всі вони охоплюють і що логіка, яку вони інкапсулюють, може бути асинхронною, має сенс, що Дії також з самого початку просто зробили б асинхронними.

Часто підкреслюється, що дії можуть бути асинхронними, тоді як мутації, як правило, ні. Ви можете вирішити бачити розмежування як вказівку на те, що мутації повинні використовуватися для чогось синхронного (і дії для будь-чого асинхронного); однак, ви зіткнетесь з деякими труднощами, якщо, наприклад, вам потрібно було зробити кілька мутацій (синхронно) або якщо вам потрібно було працювати з Getter зі своїх мутацій, оскільки функції мутації не отримують ні Геттерс, ні Мутації як аргументи ...

... що призводить до цікавого питання.

Чому мутації не отримують Геттерів?

Я ще не знайшов задовільної відповіді на це питання. Я бачив деякі пояснення основної команди про те, що я знайшов суперечки в кращому випадку. Якщо я підсумую їх використання, то Getters мають на увазі обчислювати (і часто кешовувати) розширення на стан. Іншими словами, вони в основному все ще є державою, хоча це вимагає певних обчислень, і вони, як правило, лише для читання. Так принаймні, як їх рекомендують використовувати.

Таким чином, запобігання мутаціям безпосередньо отримувати доступ до Getters означає, що зараз необхідна одна з трьох речей, якщо нам потрібно отримати доступ до колишнього функціоналу, запропонованого останнім: (1) або державні обчислення, що надаються Getter, дублюються десь доступними до мутації (неприємний запах) або (2) обчислене значення (або відповідний сам Геттер) передається як явний аргумент Мутації (фанки), або (3) сама логіка Геттера дублюється безпосередньо в межах мутації , без додаткової переваги кешування, передбаченого Getter (сморід).

Далі наведено приклад (2), який у більшості сценаріїв, з якими я стикався, здається "найменш поганим" варіантом.

state:{
    shoppingCart: {
        products: []
    }
},

getters:{
    hasProduct(state){
        return function(product) { ... }
    }
}

actions: {
    addProduct({state, getters, commit, dispatch}, {product}){

        // all kinds of business logic goes here

        // then pull out some computed state
        const hasProduct = getters.hasProduct(product)
        // and pass it to the mutation
        commit('addProduct', {product, hasProduct})
    }
}

mutations: {
    addProduct(state, {product, hasProduct}){ 
        if (hasProduct){
            // mutate the state one way
        } else {
            // mutate the state another way 
        }
    }
}

Мені сказане здається не лише дещо заплутаним, але й дещо "витікаючим", оскільки частина коду, присутнього в дії, явно витікає із внутрішньої логіки мутації.

На мою думку, це є ознакою компромісу. Я вважаю, що дозволити мутаціям автоматично приймати Геттерс представляє певні проблеми. Це може бути або сама конструкція Vuex, або інструментарій (vue-devtools та ін.), Або підтримка деякої відсталої сумісності, або якась комбінація всіх заявлених можливостей.

У що я не вірю, що передача Геттерів своїм мутаціям - це обов'язково знак того, що ви щось робите не так. Я вважаю це просто "латанням" одного з недоліків рамки.


1
Для мене це найкраща відповідь. Тільки прочитавши його, у мене було таке «клацання», яке ти відчуваєш, коли відчуваєш, що щось зрозумів.
Роберт Кузнір

Геттери по суті є computedвихідними. Вони доступні лише для читання. Приємнішим способом перегляду мутацій може бути видалення наявних у if elseвас. Документи vuex кажуть, що ви можете розмістити більше 1 у commitмежах дії. Тож було б логічно припустити, що ви можете здійснити певну мутацію залежно від логіки. Я розглядаю дії як спосіб продиктувати ЯКІ мутації вогнем.
Тамб

@Tamb: і State, і Getters пропонують контекстні дані. Має сенс, що вони будуть запитуватися, перш ніж вирішити, як змінити державу. Коли ця інформація може бути отримана повністю від держави, має сенс вся логіка бути інкапсульована всередині однієї мутації, оскільки вона має доступ до держави. Це стандартна операційна процедура для сетера. Що має менше сенсу - мати кардинально інший підхід просто тому, що зараз нам потрібно запитати Getter для подібної інформації.
Майкл Екока

@Tamb: Що ви пропонуєте, це те, що коли нам потрібно запитувати Getters, ми повинні змінити вищезазначений малюнок і перемістити логіку вибору на проксі-дію, яка може отримати доступ до Getter і може склеїти купу маленьких німих мутацій. Це працює, але він все ще є контурним і не вирішує неприємний запах, про який я згадую у своїй відповіді, він просто переміщує його кудись ще.
Майкл Екока

Документи кажуть, що використовувати getters, коли потрібно обчислити стан. Тому сьогодні здавалося правильним, що вони схожі на обчислювані властивості. Підкажіть, що ви отримуєте, кажучи, що дія може склеїти мутації. Документи чітко говорять про те, щоб укласти ділову логіку всередині дій.
Тамб

15

Я думаю, що відповідь TLDR полягає в тому, що мутації мають бути синхронними / транзакційними. Отже, якщо вам потрібно запустити виклик Ajax або зробити який-небудь інший асинхронний код, вам потрібно зробити це в дії, а потім здійснити мутацію після, щоб встановити новий стан.


1
Це виглядає як узагальнення документації; в чому немає нічого поганого. Однак проблема цієї відповіді полягає в тому, що те, що вона стверджує, не обов'язково відповідає дійсності. Ви МОЖЕТЕ модифікувати стан всередині мутації, коли викликаєте асинхронну функцію / AJAX, яка потім може бути змінена у повному зворотному режимі виклику. Я думаю, що саме це викликає стільки плутанини щодо того, чому дії слід використовувати для найкращих практик розвитку при роботі з Vuex. Я знаю, що це, безумовно, викликало плутанину для мене, коли я почав працювати з Vuex.
Erutan409

8

Основні відмінності дій та мутацій:

  1. Внутрішні дії можна запускати асинхронний код, але не в мутаціях. Тому використовуйте дії для асинхронного коду, інакше використовуйте мутації.
  2. Всередині дій ви можете отримати доступ до геттерів, штату, мутацій (вчинення їх), дій (відправлення їх) у мутаціях, ви можете отримати доступ до держави. Отже, якщо ви хочете отримати доступ лише до стану, використовуйте мутації, інакше використовуйте дії.

5

Відповідно до docs

Дії схожі на мутації , різниці полягають у тому, що:

  • Замість того, щоб мутувати стан, дії здійснюють мутації.
  • Дії можуть містити довільні асинхронні операції.

Розглянемо наступний фрагмент.

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++               //Mutating the state. Must be synchronous
    }
  },
  actions: {
    increment (context) {
      context.commit('increment') //Committing the mutations. Can be asynchronous.
    }
  }
})

Обробники дій ( приріст ) отримують контекстний об'єкт, який відкриває той самий набір методів / властивостей у екземплярі магазину, тож ви можете зателефонувати контекстному комітету, щоб здійснити мутацію, або отримати доступ до стану та getters через context.state та context.getters


1
чи можливий виклик з функції "мутація", метод з компонента vuejs?
Альберто Акунья

@ AlbertoAcuña У мене те саме запитання, тому що коли я намагаюся це робити, воно видає помилку, що локальна мутація не визначена.
Рутвік Гангурде

5

Відмова від відповідальності - я лише почав використовувати vuejs, тому це лише мені екстраполяція намірів дизайну.

Налагодження машинного часу використовує знімки стану та показує часові шкали дій та мутацій. Теоретично ми могли б просто actionsпоряд із записом державних установників та геттерів синхронно описувати мутацію. Але з іншого боку:

  • У нас були б нечисті входи (результати асинхронізації), які спричинили сеттери та геттери. Це буде важко дотримуватися логічно, і різні налаштування асинхронізації та геттери можуть дивно взаємодіяти. Це все ще може статися з mutationsтрансакціями, але тоді ми можемо сказати, що транзакцію потрібно вдосконалити на відміну від того, що вона є перегонною умовою в дії. Анонімні мутації всередині дії можуть легше переробити такі помилки, оскільки програмування асинхронізування крихке та складне.
  • Журнал транзакцій важко буде прочитати, оскільки не було б імені змін у стані. Це було б набагато більше кодовим і менш англійським, відсутнє логічне угрупування мутацій.
  • Це може бути складнішим і менш ефективним для приладу, що записує будь-які мутації на об'єкт даних, на відміну від тепер, де є синхронно визначені точки різниці - до і після виклику функції мутації. Я не впевнений, наскільки велика проблема.

Порівняйте наступний журнал транзакцій із названими мутаціями.

Action: FetchNewsStories
Mutation: SetFetchingNewsStories
Action: FetchNewsStories [continuation]
Mutation: DoneFetchingNewsStories([...])

З журналом транзакцій, який не має мутацій з ім’ям:

Action: FetchNewsStories
Mutation: state.isFetching = true;
Action: FetchNewsStories [continuation]
Mutation: state.isFetching = false;
Mutation: state.listOfStories = [...]

Я сподіваюся, що ви можете екстраполювати з цього прикладу потенційну додаткову складність асинхронізації та анонімних мутацій всередині дій.

https://vuex.vuejs.org/en/mutations.html

Тепер уявімо, що ми налагоджуємо додаток і дивимося на журнали мутацій devtool. Для кожної зареєстрованої мутації devtool потрібно буде робити знімки стану "до" та "після". Однак асинхронний зворотний виклик усередині прикладу мутації робить це неможливим: зворотний виклик ще не викликається, коли мутація здійснена, і девтол не може знати, коли насправді буде викликаний зворотний виклик - будь-яка мутація стану, що виконується в зворотному виклику по суті не відстежується!


4

Мутації:

Can update the state. (Having the Authorization to change the state).

Дії:

Actions are used to tell "which mutation should be triggered"

У Redux Way

Mutations are Reducers
Actions are Actions

Чому обидва ??

Коли додаток зростає, кодування та рядки будуть збільшуватися. Щоб у цей час вам доводиться керувати логікою в "Дії", а не в мутаціях, оскільки мутації - єдиний авторитет для зміни стану, він повинен бути максимально чистим.


2

Це мене теж бентежило, тому я зробив просту демонстрацію.

компонент.вью

<template>
    <div id="app">
        <h6>Logging with Action vs Mutation</h6>
        <p>{{count}}</p>
        <p>
            <button @click="mutateCountWithAsyncDelay()">Mutate Count directly with delay</button>
        </p>
        <p>
            <button @click="updateCountViaAsyncAction()">Update Count via action, but with delay</button>
        </p>
        <p>Note that when the mutation handles the asynchronous action, the "log" in console is broken.</p>
        <p>When mutations are separated to only update data while the action handles the asynchronous business
            logic, the log works the log works</p>
    </div>
</template>

<script>

        export default {
                name: 'app',

                methods: {

                        //WRONG
                        mutateCountWithAsyncDelay(){
                                this.$store.commit('mutateCountWithAsyncDelay');
                        },

                        //RIGHT
                        updateCountViaAsyncAction(){
                                this.$store.dispatch('updateCountAsync')
                        }
                },

                computed: {
                        count: function(){
                                return this.$store.state.count;
                        },
                }

        }
</script>

store.js

import 'es6-promise/auto'
import Vuex from 'vuex'
import Vue from 'vue';

Vue.use(Vuex);

const myStore = new Vuex.Store({
    state: {
        count: 0,
    },
    mutations: {

        //The WRONG way
        mutateCountWithAsyncDelay (state) {
            var log1;
            var log2;

            //Capture Before Value
            log1 = state.count;

            //Simulate delay from a fetch or something
            setTimeout(() => {
                state.count++
            }, 1000);

            //Capture After Value
            log2 = state.count;

            //Async in mutation screws up the log
            console.log(`Starting Count: ${log1}`); //NRHG
            console.log(`Ending Count: ${log2}`); //NRHG
        },

        //The RIGHT way
        mutateCount (state) {
            var log1;
            var log2;

            //Capture Before Value
            log1 = state.count;

            //Mutation does nothing but update data
            state.count++;

            //Capture After Value
            log2 = state.count;

            //Changes logged correctly
            console.log(`Starting Count: ${log1}`); //NRHG
            console.log(`Ending Count: ${log2}`); //NRHG
        }
    },

    actions: {

        //This action performs its async work then commits the RIGHT mutation
        updateCountAsync(context){
            setTimeout(() => {
                context.commit('mutateCount');
            }, 1000);
        }
    },
});

export default myStore;

Дослідивши це, висновок, до якого я дійшов, полягає в тому, що мутації - це умова, орієнтована лише на зміну даних, щоб краще розділити проблеми та покращити журнал до та після оновлених даних. Тоді як дії - це шар абстракції, який обробляє логіку вищого рівня, а потім викликає мутації відповідним чином


0

1.З документа :

Дії схожі на мутації, різниці полягають у тому, що:

  • Замість того, щоб мутувати стан, дії здійснюють мутації.
  • Дії можуть містити довільні асинхронні операції.

Дії можуть містити асинхронні операції, але мутація не може.

2.Ми викликаємо мутацію, ми можемо змінити стан безпосередньо. і ми також можемо в дії змінити стани таким чином:

actions: {
  increment (store) {
    // do whatever ... then change the state
    store.dispatch('MUTATION_NAME')
  }
}

Дії призначені для обробки ще інших речей, ми можемо робити багато речей там (ми можемо використовувати асинхронні операції), а потім змінювати стан диспетчерською мутацією.


0

Тому що немає жодної держави без мутацій! Коли це зроблено - виконується певна логіка, яка передбачувано змінює стан. Мутації - єдиний спосіб встановити або змінити стан (так що прямих змін немає!), А крім того - вони повинні бути синхронними. Це рішення забезпечує дуже важливу функціональність: мутації входять у devtools. І це забезпечує вам велику читабельність та передбачуваність!

Ще одне - дії. Як уже було сказано, дії вчиняють мутації. Тому вони не змінюють магазин, і немає необхідності в тому, щоб вони були синхронними. Але вони можуть керувати додатковим фрагментом асинхронної логіки!


0

Можливо, здається, зайвий шар actionsпросто для виклику mutations, наприклад:

const actions = {
  logout: ({ commit }) => {
    commit("setToken", null);
  }
};

const mutations = {
  setToken: (state, token) => {
    state.token = token;
  }
};

Отже, якщо виклики actionsдзвінків logout, чому б не викликати саму мутацію?

Вся ідея дії полягає в тому, щоб викликати кілька мутацій всередині однієї дії або зробити запит Ajax або будь-яку асинхронну логіку, яку ви можете собі уявити.

Зрештою, ми можемо мати дії, які викликають декілька мережевих запитів і, нарешті, викликають багато різних мутацій.

Таким чином, ми намагаємося максимально скласти складну частину від нашої Vuex.Store(), actionsі це залишає наше mutations, stateі gettersбільш чітке та прямолінійне, і узгоджується з тим видом модульності, який робить бібліотеки типу Vue та React популярними.


0

Я використовую Vuex професійно близько 3 років, і ось що, на мою думку, я зрозумів про суттєві відмінності між діями та мутаціями, як можна отримати користь від їхнього спільного використання, і як можна ускладнити життя, якщо ви не використовуй це добре.

Основна мета Vuex - запропонувати новий зразок для контролю поведінки вашої програми: Реактивність. Ідея полягає в тому, щоб вивантажити оркестрацію стану вашої заявки на спеціалізований об’єкт: магазин. Це зручно надавати методи підключення компонентів безпосередньо до даних вашого магазину, щоб використовувати їх у власні зручності. Це дозволяє вашим компонентам зосередитись на своїй роботі: визначити шаблон, стиль та поведінку основних компонентів, які представлятимуть користувачеві. Тим часом магазин обробляє велике навантаження даних.

Це не лише єдина перевага цього шаблону. Той факт, що магазини є єдиним джерелом даних для всієї програми, пропонує великий потенціал повторної використання цих даних для багатьох компонентів. Це не перша модель, яка намагається вирішити цю проблему міжкомпонентної комунікації, але там, де вона світиться, це те, що вона змушує вас реалізувати дуже безпечну поведінку для вашої програми, в основному забороняючи своїм компонентам змінювати стан цих спільних даних , і змусити замість цього використовувати "загальнодоступні точки", щоб запитати про зміни.

Основна ідея така:

  • У магазині є внутрішній стан, до якого ніколи не можна отримати прямий доступ до компонентів (mapState фактично заборонено)
  • У магазині є мутації, які є синхронною модифікацією до внутрішнього стану. Єдиною роботою мутації є зміна стану. Їх слід викликати лише з дії. Їх слід назвати, щоб описати речі, які трапилися зі станом (ORDER_CANCELED, ORDER_CREATED). Зберігайте їх короткими і солодкими. Ви можете перейти через них, скориставшись розширенням браузера Vue Devtools (це чудово і для налагодження!)
  • У магазині також є дії, які мають бути асинхронізувати або повертати обіцянку. Це дії, які будуть викликати ваші компоненти, коли вони захочуть змінити стан програми. Їх слід назвати діловими орієнтованими діями (дієслова, тобто cancelOrder, createOrder). Тут ви підтверджуєте та надсилаєте свої запити. Кожна дія може викликати різні дії на різному кроці, якщо потрібно змінити стан.
  • Нарешті, у магазині є геттери, які ви використовуєте для викриття свого стану своїм компонентам. Розраховуйте, що вони будуть широко використовуватися у багатьох компонентах у міру розширення програми. Vuex сильно кеширує геттери, щоб уникнути марних циклів обчислень (доки ви не додасте параметри до свого геттера - намагайтеся не використовувати параметри), тому не соромтесь широко використовувати їх. Просто переконайтеся, що ви даєте імена, які якомога ближче описують, у якому стані знаходиться програма.

Коли це було сказано, магія починається, коли ми починаємо проектувати наше застосування таким чином. Наприклад:

  • У нас є компонент, який пропонує перелік замовлень користувачеві з можливістю видалити ці замовлення
  • Компоненти склали карту getter store (deletableOrders), що представляє собою масив об'єктів з ідентифікаторами
  • У компонента є кнопка в кожному рядку замовлень, а її натискання відображається на дію магазину (deleteOrder), яка передає йому об’єкт замовлення (який, ми пам’ятаємо, походить із самого списку магазину)
  • Дія deleteOrder у магазині виконує такі дії:
    • це підтверджує видалення
    • він зберігає наказ про тимчасове видалення
    • він здійснює мутацію ORDER_DELETED із замовленням
    • він надсилає виклик API, щоб фактично видалити замовлення (так, ПІСЛЯ змінити стан!)
    • він чекає завершення виклику (стан уже оновлено), а після відмови ми викликаємо мутацію ORDER_DELETE_FAILED із замовленням, яке ми зберігали раніше.
  • Мутація ORDER_DELETED просто видалить заданий порядок зі списку видалених замовлень (що оновить отримувач)
  • Мутація ORDER_DELETE_FAILED просто повертає її назад і змінює стан, щоб повідомляти про помилку (інший компонент, повідомлення про помилку, відстежує цей стан, щоб знати, коли він повинен відображатися)

Зрештою, у нас є досвід користувача, який вважається "реактивним". З точки зору нашого користувача, пункт був негайно видалений. Здебільшого ми очікуємо, що наші кінцеві точки просто працюватимуть, тому це ідеально. Коли це не вдалося , ми все ще маємо певний контроль над тим, як буде реагувати наша програма , оскільки ми успішно розділили стурбованість станом нашої додаткової програми, фактичними даними.

Майте на увазі, вам не завжди потрібен магазин. Якщо ви виявите, що ви пишете магазини, які виглядають приблизно так:

export default {
  state: {
    orders: []
  },
  mutations: {
    ADD_ORDER (state, order) {
       state.orders.push(order)
    },
    DELETE_ORDER (state, orderToDelete) {
       state.orders = state.orders.filter(order => order.id !== orderToDelete.id)
    }
  },
  actions: {
    addOrder ({commit}, order) {
      commit('ADD_ORDER', order)
    },
    deleteOrder ({commit}, order) {
      commit('DELETE_ORDER', order)
    }
  },
  getters: {
    orders: state => state.orders
  }
}

Мені здається, ви використовуєте магазин лише як сховище даних і, можливо, пропускаєте його в аспекті реактивності, не дозволяючи йому також взяти під контроль змінні, на які реагує ваша програма. В основному, ви можете і, ймовірно, можете завантажувати в магазини деякі рядки коду, написані у ваших компонентах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.