State — центральное хранилище данных приложения. Он представляет собой объект, в котором содержится всё состояние, используемое компонентами. Основная идея заключается в том, что единственным источником истины для данных становится store, а не локальные состояния отдельных компонентов.
State должен быть:
Пример объявления state:
const store = createStore({
state() {
return {
count: 0,
user: {
id: null,
name: ''
},
isAuthenticated: false
}
}
})
Использование функции для возврата state обязательно, так как это предотвращает утечки состояния при создании нескольких экземпляров store (актуально для SSR).
Доступ к state внутри компонентов осуществляется через объект store:
this.$store.state.count
или с использованием Composition API:
import { useStore } from 'vuex'
const store = useStore()
console.log(store.state.count)
Прямое изменение state запрещено. Это правило обеспечивает прозрачность потока данных и упрощает отладку. Все изменения должны происходить через специальные механизмы.
Getters — это вычисляемые свойства для store. Они используются для получения производных данных на основе state, аналогично computed-свойствам в компонентах.
Основные задачи getters:
Пример getter:
const store = createStore({
state() {
return {
todos: [
{ id: 1, text: 'Изучить Vue', done: true },
{ id: 2, text: 'Изучить Vuex', done: false }
]
}
},
getters: {
completedTodos(state) {
return state.todos.filter(todo => todo.done)
},
completedCount(state, getters) {
return getters.completedTodos.length
}
}
})
Getters получают:
state — текущее состояние;getters — доступ к другим getters;rootState и rootGetters — при
использовании модулей.Доступ к getters:
this.$store.getters.completedCount
или:
store.getters.completedCount
Getters кэшируются на основе зависимостей. Пересчёт происходит только при изменении используемых значений state, что положительно влияет на производительность.
Actions отвечают за выполнение логики, связанной с изменением состояния. В отличие от mutations, они могут быть асинхронными и содержать побочные эффекты: HTTP-запросы, таймеры, работу с API браузера.
Основные характеристики actions:
Пример action:
const store = createStore({
state() {
return {
count: 0
}
},
mutations: {
increment(state, payload) {
state.count += payload
}
},
actions: {
incrementAsync({ commit }, payload) {
return new Promise(resolve => {
setTimeout(() => {
commit('increment', payload)
resolve()
}, 1000)
})
}
}
})
Контекст action (context) предоставляет доступ к:
stategetterscommitdispatchrootStaterootGettersЧаще всего используется деструктуризация:
actions: {
fetchUser({ commit }) {
// логика загрузки данных
}
}
Вызов action из компонента:
this.$store.dispatch('incrementAsync', 5)
или с использованием async/await:
await store.dispatch('incrementAsync', 5)
Actions подходят для:
Архитектура state management строится на однонаправленном потоке данных:
dispatch)commit)Такой подход обеспечивает:
Эти три сущности работают как единый механизм:
Пример связанной логики:
state: {
products: [],
loading: false
},
getters: {
availableProducts(state) {
return state.products.filter(p => p.available)
}
},
actions: {
async loadProducts({ commit }) {
commit('setLoading', true)
const data = await api.getProducts()
commit('setProducts', data)
commit('setLoading', false)
}
}
Такое разделение ответственности делает код масштабируемым и удобным для сопровождения, особенно в крупных приложениях с большим количеством компонентов и сложными сценариями взаимодействия.