• Vuex ——详细介绍


    Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。可以理解为:将多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的 Vue 实例中,让其他组件可以使用,它最大的特点是响应式。

    一般情况下,我们会在 Vuex 中存放一些需要在多个界面中进行共享的信息。比如用户的登录状态、用户名称、头像、地理位置信息、商品的收藏、购物车中的物品等,这些状态信息,我们可以放在统一的地方,对它进行保存和管理。

    Vuex 插件的安装

    npm install --save vuex@3.6.2
    
    • 1

    注意版本问题:vue 的 2.x 版本对应 vuex 的 3.x 版本,vue 的 3.x 版本对应 vuex 的 4.x 版本

    在 src 目录下新建 store 文件夹,创建 index.js文件引入、安装、创建并导出Vuex对象。

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    //1.安装插件
    Vue.use(Vuex)
    
    //2.创建对象
    const store = new Vuex.Store({
      state:{
        counter:1000
      },
      mutations:{
    
      },
      actions:{
    
      },
      getters:{
    
      },
      modules:{
        
      }
    })
    //3.导出使用
    export default store
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    和 vue-router 的使用方式一样,在 main.js 文件中挂载使用

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    store 对象中存放的东西是固定的,主要有:state、mutations、actions、getters、modules

    下图是官方给出的vuex状态管理图例

    Vuex的基本使用

    安装浏览器插件:devtools 方便调试

    state:存放需要共享的状态信息,使用时通过 $store.state.counter 即可拿到状态信息。

    对 state 的状态信息进行修改:先拿到 store 对象,然后通过commit 提交 mutations 中的方法。

    使用 devtools调试界面,可以跟踪查看每一次事件操作。

    Vuex 核心概念

    State:

    单一状态树即单一数据源,在一个项目中只使用一个store对象,来存储所有共享的状态信息。

    Getters:

    类似于计算属性,在数据展示前进行一些变化处理,具有缓存功能,能够提高运行效率。eg:

      getters:{
        powerCounter(state){
          return state.counter * state.counter
        },
        more20stu(state){
          return state.students.filter(s => s.age > 20)
        },
        more20stuLength(state,getters){
          return getters.more20stu.length
        },
        moreAgeStu(state){
          return function(age){
            return state.students.filter(s => s.age > age)
          }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    使用时,通过:$store.getters.powerCounter 获取:

        

    {{$store.getters.powerCounter}}

    {{$store.getters.more20stu}}

    {{$store.getters.more20stuLength}}

    {{$store.getters.moreAgeStu(18)}}

    • 1
    • 2
    • 3
    • 4

    需要手动传参数时,可以在 getters 中返回一个 function:eg

        moreAgeStu(state){
          return function(age){
            return state.students.filter(s => s.age > age)
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    调用时传入参数即可:

    {{$store.getters.moreAgeStu(18)}}

    • 1

    Mutations:

    store/index.js

      mutations:{//定义一些方法
        increment(state){
          state.counter++
        },
        decrement(state){
          state.counter--
        },
        incrementCount(state, payload){
          //1.普通提交方式
          //state.counter += count
          //2.特殊提交方式
          state.counter += payload.count
        },
        addStudent(state, obj){
          state.students.push(obj)
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    组件调用 :传递的参数(payload)可以是一个对象

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    mutations在处理异步操作时,能够引起页面的响应式变化,但是 devtools 无法进行监听。

    比如:在 mutations 中执行以下代码

        updateInfo(state){
          setTimeout(() => {
            state.info.name = 'James'
          }, 1000);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Actions:

    如果确实需要进行一些异步操作,比如网络请求,建议在 Actions 中进行处理,这样 devtools 就能够进行跟踪,由 Actions 处理异步操作,具体的函数部分仍交由 Mutations 进行处理。

      actions:{
        //context:上下文 === store
        aUpdateInfo(context,payload){
          setTimeout(() => {
            context.commit('updateInfo',payload)
            console.log(payload);
          }, 5000);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    组件中使用时,调用:this.$store.dispatch(‘aUpdateInfo’)

        updateInfo(){
          // this.$store.commit('updateInfo')
          this.$store.dispatch('aUpdateInfo','参数')
        }
    
    • 1
    • 2
    • 3
    • 4

    结合Promise使用:

      actions:{
        //context:上下文 === store
        aUpdateInfo(context, payload){
          return new Promise((resolve, reject)=>{
            setTimeout(() => {
              context.commit('updateInfo');
              console.log(payload);
              resolve('11111')
            }, 1000);
          })
        }
      }
    
        updateInfo(){
          // this.$store.commit('updateInfo')
          this.$store
          .dispatch('aUpdateInfo','参数')
          .then(res =>{
            console.log('里面完成了提交');
            console.log(res);
          })
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Modules:

    分模块管理数据

    const moduleA = {
      state:{
        name: 'moduleA'
      },
      mutations:{
        updateName(state,payload){
          state.name = payload
        }
      },
      getters:{
        fullname(state){
          return state.name + '1111'
        },
        fullname2(state, getters){
          return getters.fullname + '2222'
        },
        fullname3(state, getters, rootState){
          //传入第三个参数:rootState为上一个store对象中的state
          return getters.fullname2 +rootState.counter
        }
      },
      actions:{
        aUpdateName(context){//context 中 的commit只指向该模块中的mutations
          setTimeout(() => {
            context.commit('updateName','xiaowang')
            console.log(context)
          },
    
    const store = new Vuex.Store({
      state:{
        counter:1000,
        students:[
          {id:110, name: 'name1', age: 12},
          {id:111, name: 'name2', age: 21},
          {id:112, name: 'name3', age: 22},
          {id:113, name: 'name4', age: 20},
          {id:114, name: 'name5', age: 18}
        ],
        info:{
          name: 'kobe',
          age: 40,
          height: 1.89
        }
      },
      mutations:{//定义一些方法
        increment(state){
          state.counter++
        },
        decrement(state){
          state.counter--
        },
        incrementCount(state, payload){
          //1.普通提交方式
          //state.counter += count
          //2.特殊提交方式
          state.counter += payload.count
        },
        addStudent(state, obj){
          state.students.push(obj)
        },
        updateInfo(state){
          state.info.name = 'Jams'//响应式:事先定义过的为响应式
          // state.info['address'] = 'chengdu'//响应式
          // Vue.set(state.info,'address1','Asgin')//响应式
          // delete state.info.age//响应式
          // Vue.delete(state.info,'height')//响应式
        }
      },
      getters:{
        powerCounter(state){
          return state.counter * state.counter
        },
        more20stu(state){
          return state.students.filter(s => s.age > 20)
        },
        more20stuLength(state,getters){
          return getters.more20stu.length
        },
        moreAgeStu(state){
          return function(age){
            return state.students.filter(s => s.age > age)
          }
        }
      },
      actions:{
        //context:上下文 === store
        aUpdateInfo(context, payload){
          return new Promise((resolve, reject)=>{
            setTimeout(() => {
              context.commit('updateInfo');
              console.log(payload);
              resolve('11111')
            }, 1000);
          })
        }
      },
      modules:{
        a: moduleA
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    组件中使用 :$store.state.a

        

    Modules中的内容

    {{$store.state.a.name}}

    {{$store.getters.fullname3}}

    • 1
    • 2
    • 3
    • 4
    • 5

    执行模块中的方法 :直接 $store.commit 提交,故 mutations 之间定义的方法名不能重复。

        updateName(){
          this.$store.commit('updateName','lisa')
        },
        aupdateName(){
          this.$store.dispatch('aUpdateName')
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    打印出的 context 信息如下:

    包含根状态下的一些 state (rootState) 和 mutations (rootMutations)。

  • 相关阅读:
    网安之python基础学习作业(1)
    【读书笔记】《我们》
    刚毕业的学长真实体验:2022年软件测试行业不再吃香?毕业即失业?
    YoloV5/YoloV7独家改进:Multi-Dconv Head Transposed Attention注意力,效果优于MHSA| CVPR2022
    【Python】进阶学习:基于Matplotlib--使用plt.savefig()实现图形文件的保存
    TypeScript(5)类、继承、多态
    RPC和REST
    查询sqlserver内存分配情况的SQL
    《中国垒球》:“五个融合”打开中国垒球发展新局面
    线段树
  • 原文地址:https://blog.csdn.net/m0_67401606/article/details/126042412