Введение в Vuex
Vuex – это официальная библиотека управления состояниями для Vue.js.
Ее задача заключается в обмене данными между компонентами вашего приложения.
Компоненты в Vue.js из коробки могут взаимодействовать с помощью
- props, для передачи состояния дочерним компонентам от родительского компонента
- events, для изменения состояния родительского компонента от дочернего или используя корневой компонент в качестве шины событий.
Иногда вещи становятся сложнее, чем позволяют эти простые опции.
В этом случае хорошим вариантом является централизация состояния в едином хранилище. Именно так поступает Vuex.
Почему вам стоит использовать Vuex
Vuex – не единственный вариант управления состояниями, который вы можете использовать в Vue (вы также можете использовать Redux), но его главное преимущество в том, что он официальный, и его интеграция с Vue.js – это то, что заставляет его сиять.
С React вам придется выбирать одну из множества доступных библиотек, поскольку экосистема огромна и не имеет стандарта де-факто. В последнее время самым популярным выбором был Redux, а за ним по популярности следовал MobX. В случае с Vue я бы сказал, что вам не придется искать ничего, кроме Vuex, особенно в начале работы.
Vuex позаимствовал многие свои идеи из экосистемы React, поскольку это паттерн Flux, популяризированный Redux.
Если вы уже знакомы с Flux или Redux, Vuex будет вам очень знаком. Если нет, не беда – я объясню каждую концепцию с нуля.
Компоненты в приложении Vue могут иметь собственное состояние. Например, поле ввода будет хранить введенные в него данные локально. Это совершенно нормально, и компоненты могут иметь локальное состояние даже при использовании Vuex.
Вы знаете, что вам нужно что-то вроде Vuex, когда вы начинаете делать много работы по передаче части состояния.
В этом случае Vuex предоставляет центральное хранилище для состояния, и вы изменяете состояние, запрашивая его у хранилища.
Каждый компонент, зависящий от определенного фрагмента состояния, получает доступ к нему с помощью геттера на хранилище, что обеспечивает обновление состояния, как только оно изменится.
Использование Vuex внесет некоторую сложность в приложение, поскольку для корректной работы все должно быть настроено определенным образом, но если это поможет решить проблему неорганизованной системы передачи реквизитов и событий, которая может превратиться в беспорядочную кашу, если ее слишком усложнить, то это хороший выбор.
Давайте начнем
В этом примере я начну с приложения Vue CLI. Vuex также можно использовать, напрямую загружая его в тег скрипта, но поскольку Vuex больше подходит для больших приложений, гораздо более вероятно, что вы будете использовать его в более структурированных приложениях, таких как те, которые можно быстро запустить с помощью Vue CLI.
Примеры, которые я использую, будут размещены на CodeSandbox, который является отличным сервисом с готовыми примерами Vue CLI по адресу https://codesandbox.io/s/vue. Я рекомендую воспользоваться им, чтобы поиграть.

После этого нажмите кнопку Добавить зависимость, введите “vuex” и нажмите ее.
Теперь Vuex будет указан в списке зависимостей проекта.
Чтобы установить Vuex локально, вы можете запустить npm install vuex или yarn add vuex внутри папки проекта.
Создание Vuex store
Теперь мы готовы создать наш Vuex store.
Этот файл можно поместить куда угодно. Обычно рекомендуется поместить его в файл src/store/store.js, что мы и сделаем.
В этом файле мы инициализируем Vuex и говорим Vue использовать его:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({})Мы экспортируем объект Vuex store, который создаем с помощью API Vuex.Store().
Пример использования store
Теперь, когда у нас есть скелет, давайте придумаем идею для хорошего случая использования Vuex, чтобы я мог представить его концепции.
Например, у меня есть 2 сиблинговых компонента, один с полем ввода, а другой печатает содержимое поля ввода.
Когда поле ввода изменяется, я хочу также изменить содержимое второго компонента. Очень просто, но это поможет нам справиться с задачей.
Представляем новые компоненты, которые нам нужны
Я удаляю компонент HelloWorld и добавляю компонент Form и компонент Display.
<template> <div> <label for="flavor">Favorite ice cream flavor?</label> <input name="flavor"> </div> </template>
<template> <div> <p>You chose ???</p> </div> </template>
Добавление этих компонентов в приложение
Мы добавляем их в код App.vue вместо компонента HelloWorld:
<template>
<div id="app">
<Form/>
<Display/>
</div>
</template>
<script>
import Form from './components/Form'
import Display from './components/Display'
export default {
name: 'App',
components: {
Form,
Display
}
}
</script>Добавьте состояние в store
Итак, с этим мы возвращаемся в файл store.js и добавляем в store свойство state, которое представляет собой объект, содержащий свойство flavor. Изначально это пустая строка.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
}
})Мы будем обновлять его, когда пользователь введет текст в поле ввода.
Добавьте мутацию
Состоянием нельзя управлять иначе, чем с помощью мутаций. Мы настроим одну мутацию, которая будет использоваться внутри компонента Form для уведомления магазина о том, что состояние должно измениться.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
}
})Добавьте геттер для ссылки на свойство состояния
Когда все готово, нам нужно добавить способ просмотра состояния. Для этого мы используем геттеры. Мы создадим геттер для свойства flavor:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
},
getters: {
flavor: state => state.flavor
}
})Обратите внимание, что getters – это объект. flavor – свойство этого объекта, которое принимает состояние в качестве параметра и возвращает свойство flavor состояния.
Добавление Vuex store в приложение
Теперь магазин готов к использованию. Мы возвращаемся к коду нашего приложения, и в файле main.js нам нужно импортировать состояние и сделать его доступным в нашем приложении Vue.
Мы добавляем
import { store } from './store/store'и добавляем его в приложение Vue:
new Vue({
el: '#app',
store,
components: { App },
template: ',[object Object],'
})После добавления этого компонента, поскольку это главный компонент Vue, переменная store внутри каждого компонента Vue будет указывать на Vuex store.
Обновление состояния при действии пользователя с помощью commit
Давайте обновим состояние, когда пользователь что-то набирает.
Для этого мы используем API store.commit().
Но сначала давайте создадим метод, который будет вызываться при изменении содержимого ввода. Мы используем @input, а не @change, поскольку последний срабатывает только при перемещении фокуса с поля ввода, а @input вызывается при каждом нажатии клавиши.
<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input @input="changed" name="flavor">
</div>
</template>
<script>
export default {
methods: {
changed: function(event) {
alert(event.target.value)
}
}
}
</script>Теперь, когда у нас есть значение flavor, мы используем API Vuex:
<script>
export default {
methods: {
changed: function(event) {
this.$store.commit('change', event.target.value)
}
}
}
</script>видите, как мы ссылаемся на store, используя this.$store? Это происходит благодаря включению объекта store в инициализацию основного компонента Vue.
Метод commit() принимает имя мутации (в Vuex store мы использовали change) и полезную нагрузку, которая будет передана мутации в качестве второго параметра ее функции обратного вызова.
Использование геттера для печати значения состояния
Теперь нам нужно сослаться на геттер этого значения в шаблоне Display, используя $store.getters.flavor. Это можно убрать, потому что мы находимся в шаблоне, и это неявно.
<template>
<div>
<p>You chose {{ $store.getters.flavor }}</p>
</div>
</template>Подведение итогов
На этом введение в Vuex закончено!
Полный, рабочий исходный код доступен по адресу https://codesandbox.io/s/zq7k7nkzkm.
В этой головоломке все еще не хватает многих понятий:
- actions
- modules
- helpers
- plugins
но у вас есть основы, чтобы пойти и прочитать о них в официальной документации.
Счастливого кодинга!
Оригинал: “https://flaviocopes.com/vuex/”