在Vue.js应用程序中,状态管理是一个重要的主题。当应用程序变得复杂,组件之间的状态共享和通信变得困难,这时候使用Vuex就会变得十分有用。Vuex是一个专门为Vue.js设计的状态管理库,它提供了一个集中式的状态管理方案,使得状态的修改和访问更加直观和可维护。
1.什么是Vuex?
Vuex是一个专门为Vue.js应用程序开发的状态管理库。它借鉴了Flux和Redux的概念,采用了集中式的状态管理架构。Vuex的核心概念包括状态(State)、Mutation、Action和Getter。
-
状态(State):应用程序中的数据源,通常通过Vuex的
state
对象来表示。我们可以在组件中直接访问和使用状态,而不需要手动进行组件之间的传递。 -
Mutation:用于修改状态的方法,类似于事件。每个Mutation都有一个字符串类型的事件类型和一个回调函数,在回调函数中进行状态的修改。Mutations应该是同步的操作。
-
Action:用于处理异步操作和复杂的业务逻辑。Action提交Mutations来修改状态。它可以包含任意异步操作,如HTTP请求、定时器等。Actions是异步的操作。
-
Getter:类似于组件的计算属性,用于从状态中派生出新的数据。Getter的返回值会根据它的依赖被缓存起来,只有当依赖发生改变时才会重新计算。
2.如何使用Vuex?
使用Vuex进行状态管理需要以下几个步骤
1. 安装和配置Vuex
首先,在你的Vue.js项目中安装Vuex。可以通过npm或yarn来进行安装
npm install vuex //默认安装最新版本
npm install vuex@3.0.0 //指定版本
安装完成后,在你的主应用程序文件中导入Vuex,并使用Vue.use()来启用它
//创建store文件夹,新建一个index.js文件作为主文件,以便后续进行vuex模块区分
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
然后,创建一个新的Vuex实例,并导出它供应用程序使用
//store.js文件
export default new Vuex.Store({
// 状态、Mutations、Actions和Getters在这里定义
})
与vue-router类似,将Store实例在mian.js中挂载.
2. 定义状态(State)
在Vuex实例中,你可以定义应用程序的状态。状态可以是任何JavaScript对象,包含应用程序中需要共享的数据
export default new Vuex.Store({
state: {
count: 0,
todos: []
}
})
我们也可以进行模块化,状态和数据复杂的时候,方便管理
在tab.js中,注意在Vuex主模块中引入文件
获取state中的数据
computed: {
count() {
return this.$store.state.count
},
todos() {
return this.$store.state.todos
}
如果是采用模块化的
computed: {
count() {
return this.$store.state.tab.count
},
todos() {
return this.$store.state.tab.todos
}
mapState
辅助函数
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。我们就要使用到mapState辅助函数
computed: {
...mapState(['count', 'todos'])
}
我们首先从vuex
中导入了mapState
辅助函数。然后,在computed
选项中,使用展开运算符(...
)和mapState
函数来将count
和todos
映射为组件的计算属性。
这样,我们可以直接在模板中使用count
和todos
,而不需要使用this.$store.state.count
和this.$store.state.todos
来获取状态。
computed: {
...mapState('tab', ['count']),
...mapState('tab', ['todos'])
}
注意,在使用模块化的状态时,我们需要在mapState
函数的第一个参数中指定对应的模块名称。
例如,...mapState("tab", ["count"])
表示将counter
模块中的count
状态映射为count
计算属性。
3. 定义Mutations
定义Mutations来修改状态。每个Mutation都有一个字符串类型的事件类型和一个回调函数,在回调函数中进行状态的修改
export default new Vuex.Store({
state: {
count: 0,
todos: []
},
mutations: {
increment(state) {
state.count++
},
addTodo(state, todo) {
state.todos.push(todo)
}
}
})
4. 调用Mutations
在组件中,你可以使用`this.$store.commit()`方法来调用Mutations并修改状态
methods: {
increment() {
this.$store.commit('increment')
},
addTodo() {
this.$store.commit('addTodo', { id: Date.now(), text: this.newTodoText })
this.newTodoText = ''
}
}
模块化的方法
methods: {
increment() {
this.$store.commit('tab/increment')
},
addTodo() {
this.$store.commit('tab/addTodo', { id: Date.now(), text: this.newTodoText })
this.newTodoText = ''
}
}
mapMutations辅助函数
methods: {
...mapMutations(['increment']),
add(){
this.increment(参数)
}
}
在methods
选项中,使用mapMutations
函数将increment
Mutations映射为组件的方法。这样,我们可以直接在组件中调用increment
方法,而无需使用this.$store.commit("increment")
来提交Mutations。
如果你想给映射的Mutations方法起一个不同于Mutations名称的方法名,可以使用对象形式的映射
methods: {
...mapMutations({
increase: 'increment'
}),
add(){
this.increase(参数)
}
}
模块化方法
methods: {
...mapMutations('tab', ['increment'])
}
注意使用辅助函数需要在组件引用
5. 定义Actions
Actions用于处理异步操作和复杂的业务逻辑。它提交Mutations来修改状态。在Actions中可以包含任意异步操作,如HTTP请求、定时器等
export default new Vuex.Store({
state: {
count: 0,
todos: []
},
mutations: {
increment(state) {
state.count++
},
addTodo(state, todo) {
state.todos.push(todo)
}
},
actions: {
incrementAsync(context) {
setTimeout(() => {
context.commit('increment')
}, 1000)
}
}
})
6. 调用Actions
在组件中,你可以使用this.$store.dispatch()
方法来调用Actions
this.$store.dispatch('incrementAsync')
7. 定义Getters
Getters用于从状态中派生出新的数据,类似于组件的计算属性。Getter的返回值会根据它的依赖被缓存起来,只有当依赖发生改变时才会重新计算
export default new Vuex.Store({
state: {
todos: [
{ id: 1, text: 'Buy groceries', completed: false },
{ id: 2, text: 'Do laundry', completed: true }
]
},
getters: {
completedTodos(state) {
return state.todos.filter(todo => todo.completed)
},
incompleteTodos(state) {
return state.todos.filter(todo => !todo.completed)
}
}
})
在组件中,你可以使用this.$store.getters
来访问Getter的值
computed: {
completedTodos() {
return this.$store.getters.completedTodos
}
}