Vuex的使用分享

1、引言

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。具体来说,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、甚至更深层次的嵌套模块。
javascript 复制代码
// 安装 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)中去。

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

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

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

3.2 getters

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

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

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

3.3 mutations

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

ini 复制代码
export const mutations = {
  updateCompanyID(state,companyID) {
    state.companyID= companyID;
  },
  

使用方式:

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

3.4 actions

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

ini 复制代码
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...

相关推荐
用户059540174462 小时前
把AI对话记忆存储测试从手工改成Playwright+pytest,覆盖率从20%提到96%,回归时间缩短90%
前端·css
kyriewen2 小时前
别再这样写TypeScript了——Code Review中最常见的8个反模式
前端·javascript·typescript
名字还没想好☜2 小时前
Next.js ‘use client‘ 到底加在哪:Server/Client Components 边界与常见报错
开发语言·前端·javascript·react·next.js
午安~婉3 小时前
GitHub Token/ GitHub Stats统计显示图异常
前端·github·vercel·github token
码云之上3 小时前
AI Agent 工程化总览篇:从 Prompt 到 Harness
前端·人工智能
2501_926978333 小时前
以说明书 DNA 为模板——完整 AGI 的结构图景
前端·人工智能·经验分享·笔记·ai写作
IT_陈寒3 小时前
Vite静态资源引用这个坑我踩得有点疼
前端·人工智能·后端
程序员黑豆4 小时前
鸿蒙应用开发:AttributeModifier 使用教程
前端·harmonyos
codeniu4 小时前
TRAE Work 实战 | 从"有个想法"到线上Demo,我全程只靠对话就完成了
前端·trae
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十):增加管理员角色组管理
前端·后端·ai编程