Vuex 入门
官方给出的解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。相信很多新选手看完这段话有种绝望的感觉。开始我也是这样的,后来我想到了一个比方!
:比如某年级有5个小班,每个小班有25个同学,但是只有一个老师授课,假如5个小班就对应着5个组件,每个班的25个同学就相当于每个组件中的25条数据,这个老师就相当于 vuex ,老师讲的课就相当于每一条数据。要保证每个同学受到同样的教育,就需要这个老师把每节课分别讲5遍,还不能保证每个班的同学听到的效果相同。一段时间后,老师觉得这样特别麻烦还很累,就想了一个办法,找了一个大教室,把这5个小班的同学合并到一起,这样每个课程只需要讲一次就好啦,而且还保证了每个班的同学听到的效果相同。这就是 vuex 的作用,把各个组件中用到的数据统一管理,同步发放,省时省心省力。
那这个 vuex 怎么用呢?让我们从一个简单的 Vue 计数应用开始
一、基本用法
1. 初始化并创建一个项目
vue init webpack-simple vuex-demo
cd vuex-demo
npm install
2. 安装 vuex
npm install vuex -S
3. 在 src 目录下创建 store.js 文件,并在 main.js 文件中导入并配置
store.js 中写入
importVuefrom'vue'//引入 vuex 并 useimportVuexfrom'vuex'Vue.use(Vuex)
main.js 文件
importVuefrom'vue'importAppfrom'./App.vue'importstorefrom'./assets/store'//导入 store 对象newVue({//配置 store 选项,指定为 store 对象,会自动将 store 对象注入到所有子组件中,在子组件中通过 this.$store 访问该 store 对象 store,el:'#app',render:h=>h(App)})
4. 编辑 store.js 文件
在应用 vuex 之前,我们还是需要看懂这个流程图,其实很简单。
①Vue Components是我们的vue 组件,组件会触发(dispatch)一些事件或动作(Actions);
② 我们在组件中发出的动作,肯定是想获取或者改变数据的,但是在vuex中,数据是集中管理的,我们不能直接去更改数据,所以会把这个动作提交(Commit)到Mutations中;
③ 然后Mutations就去改变(Mutate)State中的数据;
④ 当State中的数据被改变之后,就会重新渲染(Render)到Vue Components(组件)中去,Vue Components(组件)展示更新后的数据,完成一个流程。
Vuex 的核心是Store(仓库),相当于是一个容器,一个Store实例中包含以下属性的方法:
state定义属性(状态 、数据)
getters用来获取属性
actions定义方法(动作)
commit提交变化,修改数据的唯一方式就是显示的提交 mutations
mutations定义变化,处理状态(数据)的改变
mapGetters用来获取属性(数据)
mapActions用来获取方法(动作)
store.js 中写入
// 定义属性(数据)varstate = {count:6}// 创建 store 对象conststore =newVuex.Store({ state})// 导出 store 对象exportdefaultstore;
方式1、 在app.vue中就能通过this.$store访问该 store 对象 ,获取该count。
其中需要注意的是this.$store中的store与 main.js 中配置的store相对应,一定要注意大小写
//把 count 方法直接写入,可自己执行
{{count}}
exportdefault{name:'app',computed:{ count(){//返回获取到的数据returnthis.$store.state.count } }}执行
npm run dev
就能在页面中看到传过来的数据了
方式2、vuex 提供的mapGetters和mapActions来访问
mapGetters用来获取属性(数据)
① 在app.vue中引入mapGetters
import{mapGetters}from'vuex'
② 在app.vue文件的计算属性中调用mapGetters辅助方法,并传入一个数组,在数组中指定要获取的属性count
import{mapGetters,mapActions}from'vuex'exportdefault{name:'app',computed:mapGetters([//此处的 count 与以下 store.js 文件中 getters 内的 count 相对应'count'])}
③ 在store.js中定义getters方法并导出
getters用来获取属性
importVuefrom'vue'importVuexfrom'vuex'Vue.use(Vuex)// 定义属性(数据)varstate = {count:6}// 定义 gettersvargetters={//需要传个形参,用来获取 state 属性count(state){returnstate.count }}// 创建 store 对象conststore =newVuex.Store({ state, getters})// 导出 store 对象exportdefaultstore;
这样页面上就会显示传过来的数据了!接下来我们来通过动作改变获取到的数据
④在store.js中定义actions和mutations方法并导出
actions定义方法(动作)
commit提交变化,修改数据的唯一方式就是显示的提交 mutations
mutations定义变化,处理状态(数据)的改变
importVuefrom'vue'importVuexfrom'vuex'Vue.use(Vuex)// 定义属性(数据)varstate = {count:6}// 定义 gettersvargetters={ count(state){returnstate.count }}// 定义 actions ,要执行的动作,如流程的判断、异步请求constactions ={// ({commit,state}) 这种写法是 es6 中的对象解构increment({commit,state}){//提交一个名为 increment 的变化,名字可自定义,可以认为是类型名,与下方 mutations 中的 increment 对应//commit 提交变化,修改数据的唯一方式就是显式的提交 mutationscommit('increment') }}// 定义 mutations ,处理状态(数据) 的改变constmutations ={//与上方 commit 中的 ‘increment’ 相对应increment(state){ state.count ++; }}// 创建 store 对象conststore =newVuex.Store({ state, getters, actions, mutations})// 导出 store 对象exportdefaultstore;
⑤ 在app.vue中引入mapActions,并调用
mapActions用来获取方法(动作)
import{mapGetters,mapActions}from'vuex'
调用mapActions辅助方法,并传入一个数组,在数组中指定要获取的方法increment
//这个 increment 方法与下面 methods 中的 increment 相对应增加减少
{{count}}
import{mapGetters,mapActions}from'vuex'exportdefault{name:'app',computed:mapGetters(['count']),methods:mapActions([//该 increment 来自 store.js 中导出的 actions 和 mutations 中的 increment 'increment', ])}这样就能通过button来改变获取到的count了。
现在你可以通过storel.state来获取状态对象,以及通过store.commit方法触发状态变更
注意:我们通过提交mutation的方式,而非直接改变store.state.count,是因为我们想更明确地追踪到状态的变化。