likes
comments
collection
share

Vuex的使用分享

作者站长头像
站长
· 阅读数 0

1、引言

       Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。具体来说,Vuex将组件的共享状态抽取出来,以全局单例模式管理。在这种模式下,组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为。通过定义和隔离状态管理中的各种概念,并通过强制规则维持视图和状态间的独立性,代码将会变得更结构化且易维护。

  Vuex的使用分享

       Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试(允许开发者在开发过程中回溯和查看状态的变化历史,有助于快速定位问题并进行调试)、状态快照导入导出(开发者可以方便地导出当前应用的状态快照,以便日后分析或与他人共享。同时,也可以导入之前保存的状态快照,快速恢复到某一特定状态)等高级调试功能。

2、Vuex核心概念

  • State:Vuex 中的单一状态树,以一个对象形式储存所有应用级的状态。
  • Getters:从 State 中派生出来的状态,可以认为是 Store 的计算属性。
  • Mutations:同步函数,用于更改 State 中的数据。每个 mutation 都有一个字符串的事件类型和一个回调函数。
  • Actions:异步函数,用于处理异步操作和业务逻辑,然后提交 mutation。
  • Modules:将 Store 分割成模块,每个模块拥有自己的 state、mutation、action、getter、甚至更深层次的嵌套模块。

Vuex的使用分享

// 安装 Vuex
npm install vuex --save
 
// 在 main.js 中引入 Vuex
import Vuex from 'vuex'
Vue.use(Vuex)
 
// 创建 Store
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment')
    }
  },
  getters: {
    count: state => state.count
  }
})
 
// 在 Vue 根实例中注册 store
new Vue({
  el: '#app',
  store,
  // ...
})
 
// 组件中使用 Vuex
export default {
  computed: {
    count() {
      return this.$store.getters.count
    }
  },
  methods: {
    increment() {
      this.$store.dispatch('increment')
    }
  }
}

3、实践(以toC框架为例)

3.1  state

state是状态数据,可以通过this.$store.state来直接获取状态,也可以利用vuex提供的mapState辅助函数将state映射到计算属性(computed)中去。

export const state = () => ({
  TagID:0,//当前tab的标记
  companyID:"",//当前公司
  page:1,//请求加载列表传给后台的页码,
  loading:false,//list列表是否正在加载的状态标识
  finished :false,//list列表数据是否全部加载完毕的标识
  invoiceListAll:[],//当前页面展示的所有消息的集合
  invoiceDataConfNum:["--","--","--"],//配置项tab页的开票消息数量
})

使用方式:this.$store.state.XXX

import { mapState } from 'vuex';
  computed:{
    ...mapState(['invoiceDataConfNum'])
  },
  computed:{
        // 使用计算属性表达
        title( ){
            return this.$store.state.title;
        },
        singer( ){
            return this.$store.state.singer;
        }
        

3.2 getters

有时候我们需要对 store 中的 state进行加工后再输出,

// 依赖并加工state中的数据,state中的数据也会相应改变
 getters :{
   invoiceDataConfNumOne(state){
        return state.invoiceDataConfNum+'笔'
    }
}

使用方式:this.$store.getters.invoiceDataConfNumOne

3.3  mutations

更改Vuex中的状态的唯一方法是提交 mutation

export const mutations = {
  updateCompanyID(state,companyID) {
    state.companyID= companyID;
  },
  

使用方式:

this.$store.commit("updateCompanyID",this.companyID);

3.4 actions

Action 提交的是 mutation,而不是直接变更状态,Action 可以包含任意异步操作。

import {getSettleBillInvoiceList} from '../page-modules/inv/invoiceCenter/RequestInvoice';

export const actions = {
  updateListData({commit,state}, that) {
    getSettleBillInvoiceList(that).then(res=>{
      let result = res.data;
      commit("updateLoading",false)
     let cdata = result.data.rows;
      cdata = cdata.map((a)=>{
        a.isChecked = false;
        return a;
      })
      //非第一页数据要拼接数组
      if(state.page==1&&cdata.length ==0){
        commit("updateFinished",true);
      }
      cdata = state.invoiceListAll.concat(cdata) ;
      commit("updateInvoiceListAll",cdata);
      commit("updateInvoiceDataConfNum",[result.data.total1,result.data.total2,result.data.total3]);
    }).catch(err=>{
      console.log(err)
      that.$TM.Toast.fail({ type: 'warning', message: "网络异常,获取数据失败" });
    })
  },

}

使用方式:this.$store.dispatch('updateListData',this)

3.5 modules

index.js为根模块,child1.js与child2.js两个子模块

store中的js写法如上所示,没有区别,只是取值调用时不同,如下:

  •  取根模块中的值:this.$store.state.totalPrice
  •  取子模块中的值:this.$store.state.child2.num
  •  取子模块中的值:this.$store.state.child1.price
  • 使用根模块的mutation中的方法:this.$store.commit('totalPrice')
  • 使用子模块的mutation中的方法:this.$store.commit('child2/getNum',参数) 
  • 使用子模块的mutation中的方法:this.$store.commit('child1/getPrice',参数) 

参考文档:

1、v2.cn.vuejs.org/v2/guide/st…

2、vuex.vuejs.org/zh/

3、v2.nuxt.com/docs/direct…