Vuex 是专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
在 Vue 应用中,组件之间需要共享数据:
当应用变得复杂时,这种分散的状态管理方式变得难以维护。Vuex 提供了一个统一的状态管理中心,解决了这些问题。
Vuex 包含以下核心概念:
单一状态树,存储应用的所有状态:
const store = new Vuex.Store({
state: {
count: 0,
user: null,
todos: []
}
})
类似计算属性,对 state 进行派生:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '学习 Vue', done: true },
{ id: 2, text: '学习 Vuex', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
同步更改状态:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
},
incrementBy(state, payload) {
state.count += payload.amount
}
}
})
异步操作,提交 mutation:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
模块化组织代码:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA
}
})
npm install vuex --save
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
export default store
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
export default {
computed: {
count() {
return this.$store.state.count
}
},
methods: {
increment() {
this.$store.commit('increment')
}
}
}
Vuex 使用单向数据流:
View -> Action -> Mutation -> State -> View
// 事件总线
const bus = new Vue()
// 发送事件
bus.$emit('event-name', data)
// 接收事件
bus.$on('event-name', data => {
// 处理数据
})
缺点:
// 发送
this.$store.dispatch('actionName', data)
// 接收
computed: {
data() {
return this.$store.state.data
}
}
优点:
推荐的项目结构:
store/
├── index.js # 组装模块并导出 store
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
├── getters.js # 根级别的 getter
└── modules/
├── user.js # 用户模块
├── cart.js # 购物车模块
└── products.js # 产品模块
在严格模式下,任何 Mutation 外的状态修改都会抛出错误:
const store = new Vuex.Store({
strict: process.env.NODE_ENV !== 'production'
})
不要在发布环境下启用严格模式,以避免性能损失。
export default {
computed: {
message: {
get() {
return this.$store.state.message
},
set(value) {
this.$store.commit('setMessage', value)
}
}
}
}
<input v-model="message">
Vuex 核心要点: