Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。在 Vuex 中,有几个核心概念或属性,它们共同协作来管理应用的状态。
- State:
- State 是 Vuex 中的基本数据对象,用于存储应用的状态。你可以把它想象成一个全局的变量仓库,所有的组件都可以从中获取或修改状态。
- 在 Vuex 中,你需要在 store 中定义 state,并在组件中通过
this.$store.state
来访问它们,或者使用 Vuex 提供的辅助函数mapState
来简化访问。
- Getters:
- Getters 类似于 Vue 组件中的计算属性。它们基于 state 中的某些状态返回一些值,并且 getters 的返回值会根据其依赖的 state 的变化而自动变化。
- Getters 可以被认为是 store 中的计算属性。
- 访问 getters 的方式是通过
this.$store.getters
或使用辅助函数mapGetters
。
- Mutations:
- Mutations 是 Vuex 中唯一允许更新应用状态的方法。它们必须是同步函数。
- 每个 mutation 都有一个字符串的事件类型 (type) 和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更新的地方,并且它会接受 state 作为第一个参数。
- 触发 mutations 的方式是调用
this.$store.commit('mutationName', payload)
,其中 'mutationName' 是你定义的 mutation 的名称,payload 是传给 mutation 的数据。
- Actions:
- Actions 类似于 mutations,不同之处在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
- 你可以通过
this.$store.dispatch('actionName', payload)
来分发 action。 - Actions 通过调用
commit
方法来触发 mutations,并可以包含任何异步操作。
- Actions 类似于 mutations,不同之处在于:
- Modules:
- 当 Vuex 应用变得非常复杂时,store 对象可能变得相当臃肿。为了解决这个问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
- 使用模块可以让每一个模块拥有自己的命名空间,这样模块内部的 action、mutation 和 getter 的注册都会自动根据模块注册的路径调整命名。
// user.js模块中 const state = { userInfo: { name:'lucy', age:17 } } const mutations = { setUser (state, newUserInfo) { state.userInfo = newUserInfo } } const actions = { setUserSecond (context, newUserInfo) { setTimeout(() => { context.commit('setUser', newUserInfo) },2000) } } const getters = { UpperCaseName (state) { return state.userInfo.name.toUpperCase() } } export default { namespaced:true, //开启命名空间 state, mutations, actions, getters }
这些属性共同构成了 Vuex 的核心功能,使得 Vuex 成为一个强大且灵活的状态管理库。
HelloWorld.vue组件
<template>
<div class="hello">
<h1>{{ $store.state.sum }}</h1>
<button @click="add">+</button>
</div>
</template>
<script>
export default {
data(){
return{
n:3
}
},
methods:{
add(){
this.$store.dispatch('add',this.n)
// this.$store.commit('addSum',this.n)直接调用mutations
//第二个值是传递的参数,只能传递一个,如果需要多个可以包装成一个对象
}
}
}
</script>
<style scoped lang="less">
</style>
store/index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//存放数据
state: {
sum:0,
list:[1,2,3,4,5,6,7,8,9,10]
},
//修改state存放的数据
mutations: {
addSum(state,value){
state.sum += value
}
},
actions: {
add(context,value){
//这里使用setTimeout模拟异步,以后大部分场景是发送请求
setTimeout(() => {
context.commit('addSum',value)
},2000)
}
},
//第一个参数必须是 state 为了获取state里面的数据,然后进行处理
//必须要有返回值
//单向数据流,只能获取不能修改,修改需要使用mutations
getters: {
filterList (state) {
return state.list.filter(item => item > 5)
}
},
// 命名空间
import user from './modules/user'
// store/user.js文件
// 访问 ...mapState(['user', ['userInfo'])
// 直接访问 this.$store.state.模块名.XXX 所有的模块都会以对象的形式存储在state里面
// ...mapGetters('user', ['UpperCaseName'])
// this.$store.getters['user/UpperCaseName']
// ...mapMutations('user',['setUser'])
使用: setUser({
name:'luckly',
age:'18'
})
// this.$store.commit('user/setUser', {
name: 'luckly',
age:'18'
}
}
// ...mapActions('user',['setUserSecond']
// this.$store.dispatch('user/setUserSecond',{
name:'luckly',
age:18
}
modules: {
user,
}
})
Vuex 的辅助函数
Vuex 的辅助函数(Helpers)主要用来简化在组件中使用 Vuex 的过程。这些辅助函数包括 mapState
、mapGetters
、mapMutations
、mapActions
等,它们允许你将 store 中的状态(state)、计算属性(getters)、mutations 和 actions 映射到组件的局部计算属性(computed)或方法中。
1. mapState
mapState
辅助函数帮助我们将 store 中的状态映射到本地计算属性中。
<template>
<div>
<p>{{ count }}</p>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
// 使用对象展开运算符将每个 state 映射为计算属性
...mapState([
'count' // 映射 this.count 为 store.state.count
]),
// 你也可以传递一个函数来返回状态
// 这种方式适合当你想从 state 中派生出一些状态
localComputed() {
return this.$store.state.count + 1;
}
}
}
</script>
2. mapGetters
mapGetters
辅助函数用于将 store 中的 getters 映射到组件的计算属性中。
<template>
<div>
<p>{{ doubleCount }}</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
computed: {
// 使用对象展开运算符将 getter 映射为计算属性
...mapGetters([
'doubleCount' // 映射 this.doubleCount 为 store.getters.doubleCount
])
}
}
</script>
3. mapMutations
mapMutations
辅助函数将组件中的 methods 映射为 store.commit
调用(使得 this.$store.commit(...) 变为 this.xxx() 调用)。
<template>
<button @click="increment">Increment</button>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
methods: {
...mapMutations([
'increment' // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
])
}
}
</script>
4. mapActions
mapActions
辅助函数将组件的 methods 映射为 store.dispatch
调用(使得 this.$store.dispatch(...) 变为 this.xxx() 调用)。
<template>
<button @click="incrementAsync">Increment Async</button>
</template>
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions([
'incrementAsync' // 将 `this.incrementAsync()` 映射为 `this.$store.dispatch('incrementAsync')`
])
}
}
</script>
这些辅助函数可以极大地减少模板和组件逻辑中的冗余,使得 Vuex 的使用更加简洁和直观。