实现一个简单的vuex

388 阅读3分钟

Vuex 是什么

       Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,解决多组间数据通信。

要点:

  1. vue 官方搭配,专属使用(类似于: vue-router),有专门的调试工具
  2. 集中式管理数据状态方案(操作更简洁) data() { return { 数据,状态 }}
  3. 数据变化是可预测的 (响应式)        vue官方提供的独立于组件体系之外的,管理公共数据的工具

image.png

在项目中使用 Vuex

在新项目中使用:

       在配置 vue-cli 中创建项目时,就可以直接选中 Vuex 项,这样就不用做任何配置了(脚手架会自动帮我们完成)。如下图所示:

在老项目中使用:

1.在小黑窗输入 npm install vuex@3.6.2 安装包

image.png

2.配置:

       2.1 创建 Vuex.store 实例 在 store/index.js (创建 store 文件夹-> index.js )中放置具体的代码,具体如下:

 1    import Vue from 'vue'
 2    import Vuex from 'vuex'
 3    
 4    Vue.use(Vuex)
 5    
 6    const store = new Vuex.Store({
 7      state(){
 8        return {
 9          // 就是公共的数据,所有的组件都可以直接使用
10           count: 100
11         }
12       }
13     })
14     export default store

       2.2 向 Vue 实例注入 store

       在 src/main.js 中:
       1. 导入 store        2. 并注入 Vue 实例

 1    // 省略其他
 2    // 1. 导入store
 3    import store from './store' 
 4    
 5    new Vue({
 6      // 省略其他...
 7      store // 2. 注入Vue实例
 8    })

使用,在组建中使用 store

       在任意组件中,通过this.$store.state 来获取公共数据如下图所示:

image.png

       使用插值{{}}拿数据 image.png

Vuex-sate 定义公共数据并在组件中使用

state 的作用:

vuex 用它来保存公共数据
state: 统一定义公共数据(类似于 data(){return{a:1,b:2,xxxxx}})

格式:

 1    new Vuex.store({
 2      state() {
 3        return {
 4           属性名: 属性值 
 5        }
 6      }
 7    })

在组件中,通过this.$store.state.属性名来访问。
在模板中,则可以省略this而直接写成: {{$store.state.属性名}}

image.png

示例:

image.png

image.png 独立于组件体系之外,跟父子关系兄弟关系没有影响,随便哪个组件都可以交互都可以直接拿

image.png image.png

小结

state 的作用是:保存公共数据(多组件中共用的数据)
state 是响应式的: 如果修改了数据,相应的在视图上的值也会变化。

Vuex-用mutations修改公共数据

mutations作用

通过调用 mutations来修改定义在 state 中的公共数据。

image.png

格式:

分两个格式: 定义格式,调用格式

定义格式

 1    new Vue.store({
 2      // 省略其他...
 3      mutations:{
 4        // 每一项都是一个函数,可以声明两个形参
 5      	mutation名1function(state [, 载荷]) {
 6      
 7        },
 8        mutation名2function(state [, 载荷]) {
 9      
10         }
11     	}
12     })

       每一项都是一个函数,可以声明两个形参:

  • 第一个参数是必须的,表示当前的state。在使用时不需要传入
  • 第二个参数是可选的,表示载荷,是可选的。在使用时要传入的数据

使用格式

 1    this.$store.commit('mutation名', 实参)

示例

image.png

image.png

小结

       mutations 的中文含义是:变异。 它是Vuex 中用来修改公共数据的唯一入口。
       在定义时:它的第一个参数是state,第二个参数是载荷
       在调用时:用 this.$store.commit('mutation名', 载荷) 来调用

Vuex-用getters的派生状态

getters作用

类似于computed(计算属性,对现有的状态进行计算得到新的数据-------派生  )

图示

image.png

定义格式

 1    new Vuex.store({
 2      // 省略其他...
 3      getters: {
 4        // state 就是上边定义的公共数据state
 5        getter的名字1: function(state) {
 6          return 要返回的值
 7        }
 8      }
 9    })

使用格式

    在组件中通过:$store.getters.getter的名字 来访问

示例:

利用axios, mutation, state来发请求数据,getters求总价格

image.png

image.png

Vuex-state-mutation-getters 小结

                                                                      图示 image.png

Vuex-actions-发异步请求

actions介绍

  • actionsvuex 的一个配置项
  • 作用: 发异步请求获取数据,调用 mutations 来保存数据,将整个 ajax 操作封装到 Vuex 的内部        要点:
  1. action 内部可以发异步请求操作
  2. action 是间接修改 state 的: 是通过调用 mutation 来修改 state

定义格式:

 1    new Vuex.store({
 2      // 省略其他...
 3      actions: {
 4        // context对象会自动传入,它与store实例具有相同的方法和属性
 5        action的名字: function(context, 载荷) {
 6          // 1. 发异步请求, 请求数据
 7          
 8          // 2. commit调用mutation来修改数据
 9          
10           // context.commit('mutation名', 载荷)
11         }
12       }
13     })

调用格式:

    在组件中通过 this.$store.dispatch('actions的名字', 参数) 来调用action
    

image.png

示例

修改上面例子中的发请求图书的代码,将 axios 的部分写到 action

image.png image.png

小结

action 一般用来发异步请求,数据回来之后,再去调用 mutations 来保存数据

image.png

ajax 请求放在 actions 中的好处:

  1. 代码得到了进一步封装。将发 ajax 和保存数据到 vuex 绑定在一起。
  2. 逻辑更通顺。如果数据需要保存在 Vuexstate 中,那从接口处获取数据的操作就定义在 Vuexactions 中。

Vuex-用modules来拆分复杂业务

modules 的作用

拆分模块,把复杂的场景按模块来拆开

格式

 1     export default new Vuex.Store({
 2       // state: 用来保存所有的公共数据
 3       state: {},
 4       getters: {},
 5       mutations: {},
 6       actions: {},
 7       modules: {
 8       	模块名1: {
 9         		// namespaced为true,则在使用mutations时,就必须要加上模块名
10          	namespaced: true, 
11        		  state: {},
12        			getters: {},
13        			mutations: {},
14        			actions: {},
15        			modules: {}
16        	},
17          模块名2: {
18              // namespaced不写,默认为false,则在使用mutations时,不需要加模块名
19        		  state: {},
20        			getters: {},
21        			mutations: {},
22        			actions: {},
23               modules: {}
24        	}  
25        }
26      })

访问数据和修改数据的调整

访问模块中的数据,要加上模块名

 1    获取数据项:  {{$store.state.模块名.数据项名}}
 2    获取getters: {{$store.getters['模块名/getters名']}}

访问模块中的mutations/actions:
如果namespaced为true,则需要额外去补充模块名
如果namespaced为false,则不需要额外补充模块名

 1    $store.commit('mutations名')        // namespaced为false
 2    $store.commit('模块名/mutations名')  // namespaced为true
 3    
 4    $store.dispatch('actions名')        // namespaced为false
 5    $store.dispatch('模块名/actions名')  // namespaced为true

小结

使用了 modules 之后,在访问数据时就要额外添加 modules 的名字了。

结论: 在使用 modules 时,建议都给加上 namespaced