Состояние
Единое дерево состояний
Vuex использует единое дерево состояний — то есть, этот единственный объект содержит всё состояние приложения на уровне приложения и служит «единственным источником истины». Это также означает, что обычно для каждого приложения у вас будет только один store. Единое дерево состояний упрощает поиск конкретной части состояния и позволяет легко создавать снимки текущего состояния приложения для отладки.
Единое дерево состояний не конфликтует с модульностью — в последующих главах мы обсудим, как разделить ваше состояние и мутации на подмодули.
Данные, которые вы храните в Vuex, подчиняются тем же правилам, что и data в экземпляре Vue, т.е. объект состояния должен быть простым. См. также: Vue#data.
Получение состояния Vuex в компоненты Vue
Итак, как мы отображаем состояние внутри хранилища в наших компонентах Vue? Поскольку хранилища Vuex являются реактивными, самый простой способ «извлечь» состояние из него — просто вернуть некоторое состояние хранилища из вычисляемого свойства:
// let's create a Counter component
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
Всякий раз, когда store.state.count изменяется, это заставит вычисляемое свойство переоценить себя и вызовет соответствующие обновления DOM.
Однако эта схема заставляет компонент полагаться на глобальный синглтон хранилища. При использовании модульной системы требуется импортировать хранилище в каждый компонент, использующий состояние хранилища, а также требуется создание моков при тестировании компонента.
Vuex «вводит» хранилище во все дочерние компоненты из корневого компонента через систему плагинов Vue и будет доступно в них как this.$store. Давайте обновим нашу Counter реализацию:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
Помощник mapState
Когда компоненту нужно использовать несколько свойств состояния или методов хранилища, объявление всех этих вычисляемых свойств может стать повторяющимся и громоздким. Для решения этой проблемы мы можем использовать помощника mapState, который генерирует для нас вычисляемые функции-получатели, экономя наши нажатия клавиш:
// in full builds helpers are exposed as Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// arrow functions can make the code very succinct!
count: state => state.count,
// passing the string value 'count' is same as `state => state.count`
countAlias: 'count',
// to access local state with `this`, a normal function must be used
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
Мы также можем передать массив строк в mapState, когда имя сопоставленного вычисляемого свойства совпадает с именем поддерева состояния.
computed: mapState([
// map this.count to store.state.count
'count'
])
Оператор расширения объектов
Обратите внимание, что mapState возвращает объект. Как мы используем его в сочетании с другими локальными вычисляемыми свойствами? Обычно нам нужно использовать утилиту для объединения нескольких объектов в один, чтобы мы могли передать конечный объект в computed. Однако с помощью оператора расширения объектов object spread operator мы можем значительно упростить синтаксис:
computed: {
localComputed () { /* ... */ },
// mix this into the outer object with the object spread operator
...mapState({
// ...
})
}
Компоненты по-прежнему могут иметь локальное состояние
Использование Vuex не означает, что вы должны поместить всё состояние в Vuex. Хотя размещение большего состояния в Vuex делает ваши мутации состояния более явными и отлаживаемыми, иногда это также может сделать код более громоздким и косвенным. Если часть состояния строго принадлежит одному компоненту, может быть достаточно оставить её в качестве локального состояния. Вам следует взвесить компромиссы и принять решения, которые соответствуют потребностям разработки вашего приложения.
© 2015–present Evan You
Licensed under the MIT License.
https://next.vuex.vuejs.org/guide/state.html