一、vuex是什么?
官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
我们知道,在vue的组件化开发中,经常会遇到需要将当前组件的状态传递给其他组件。
然而组件通信有两种:
- 父组件 ---> 子组件通信使用:props
- 子组件 ---> 父组件通信使用:$emit
但当通信双方不是父子组件甚至压根不存在相关联系,或者一个状态需要共享给多个组件时,就会非常麻烦,数据也会很难维护,这对我们开发来讲就很不友好。这时候就需要使用vuex。
二、vuex的组成
vuex 包含有五个基本的对象:
- state:存储状态。也就是变量;
- getters:派生状态。也就是set、get中的get,有两个可选参数:state、getters分别可以获取state中的变量和其他的getters。外部调用方式:store.getters.personInfo()。就和vue的computed差不多;
- mutations:提交状态修改。也就是set、get中的set,这是vuex中唯一修改state的方式,但不支持异步操作。第一个参数默认是state。外部调用方式:store.commit('SET_AGE', 18)。和vue中的methods类似。
- actions:和mutations类似。不过actions支持异步操作。第一个参数默认是和store具有相同参数属性的对象。外部调用方式:store.dispatch('nameAsyn')。
- modules:store的子模块,内容就相当于是store的一个实例。调用方式和前面介绍的相似,只是要加上当前子模块名,如:store.a.getters.xxx()。
state
在state中定义共享状态
//state.js export default state = { count: 0 }
获取state的值,需要放在计算属性中,保证每次state能够响应式的获取
computed:{ count(){ return this.$stores.state.count //获取值 } }
这种获取方式是比较繁琐的,因此vuex给我们提供了mapState,便于我们简洁性的获取值
import { mapState } from 'vuex' export default{ computed:{ ...mapState(['count']) //这样我们在组件就可以通过this.count获取对应的值了 } }
getters
state的派生状态值,可以理解成是store的计算属性,它一般是一个方法,方法接受一个参数state。
//getter.js export default { getCount: state => state.count + 1 }
它的辅助函数是mapGetter,一般也放在computed里
import { mapGetters } from 'vuex' export default { computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters(['getCount']) } }
mutations
vuex规定更改state的值唯一方法是提交 mutation,原因是为了能够明确的追踪状态的变化,它接受2个参数(state,newVal),第二个参数可以是字符串也可以是对象
//mutations.js export default { setCount(state,newVal){ state.count = newVal } }
必须通过commit的方法触发调用它
this.$store.commit('setCount',20) //此时你把state中的count的值变成了20
它的辅助函数是mapMutations,它一般放在methods中
import { mapMutations } from 'vuex' export default { methods: { ...mapMutations(['setCount']) } }
在 Vuex 中,mutation 都是同步事务,不可写入异步操作
actions
Action 类似于 mutation,它主要用于:
- 批量的同步操作
- 异步操作
它接受一个store 实例具有相同方法和属性的 context对象,注意它提交的是 mutation,而不是直接变更状态
//actions.js export default { increment(context){ context.commit('setCount') } }
在实践中可以通过参数解构的方法简化代码
increment({commit}){ commit('setCount') }
在组件中通过分发dispatch的方法来触发action
this.$store.dispatch('increment')
这样做的目的是为了可以在action的内部执行异步操作(比如通过接口请求后才更改state的值)
increment({commit}){ setTimeout(()=>{ commit('setCount') },1000) }
也可以同步批量更改state中的值
increment({commit}){ commit('mutation1') commit('mutation2') commit('mutation3') }
它的辅助函数是mapActions,一般放在methods中
import { mapActions } from 'vuex' export default { methods: { ...mapActions(['increment']) //将 this.increment() 映射为 this.$store.dispatch('increment') } }
action的返回接收,可以返回一个Promise
export default{ actionA ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('someMutation') resolve() }, 1000) }) } }
数据接受后处理
this.$store.dispatch('actionA').then(() => { // ... })
三、vuex搭建目录
我们一般会在src目录下建立一个名为store的文件夹专门放vuex的文件,目录里存放如下:
├── index.html ├── main.js ├── components └── store ├── index.js # 我们组装模块并导出 store 的地方 ├── state.js # 跟级别的 state ├── getters.js # 跟级别的 getter ├── mutation-types.js # 根级别的mutations名称(官方推荐mutions方法名使用大写) ├── mutations.js # 根级别的 mutation ├── actions.js # 根级别的 action └── modules ├── m1.js # 模块1 └── m2.js # 模块2
ingdex.js导出store如下
import Vue from 'vue' import VueX from 'vuex' import States from './state' import Getters from './getters' import Mutations from './mutations' import Actions from './actions' Vue.use(Vuex) export default nex Vuex.Store({ State, Getters, Mutations, Actions })
然后在根目录下的main.js中全局引入
import store from './store' new Vue({ el: '#app', router, store, //在这里 template: '<App/>', components: { App } })
三、总结
自己也是边了解边使用,使用几次似乎没那么难理解。。。。。