vue2 vuex 状态管理

      Vuex 是 Vue 生态中专门用于管理应用状态(State)的库,适用于中大型 Vue 应用,解决了组件间数据共享和状态管理的复杂性。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
 
ps:vue2 安装vuex3版本 vue3安装vuex4版本不要混淆版本 
cnpm install vuex@3 -S

 

一、Vuex 核心概念

Vuex 包含 5 个核心部分:StateGetterMutationActionModule,下面逐一介绍:

1. State(状态)

  • 定义:存储应用的所有状态数据(类似组件中的 data),是唯一的数据源。
  • 使用:通过 this.$store.state 访问。
    store: {{ $store.state.count }} 

2. Getter(计算属性)

  • 定义:对 State 进行加工处理(类似组件中的 computed),可缓存结果。
  • 使用:通过 this.$store.getters 访问。
getters: {
    getCount(state) {
      return state.count
    }
  }

使用

<div>getter: {{ $store.getters.getCount }}</div>

 

3. Mutation(突变)

  • 定义:唯一修改 State 的方式,必须是同步函数(便于调试和追踪状态变化)。
  • 触发:通过 this.$store.commit('mutation名称', 参数) 调用。
this.$store.commit('add')

4. Action(动作)

  • 定义:处理异步操作(如接口请求),通过提交 Mutation 间接修改 State,可以包含任意异步操作。
  • 触发:通过 this.$store.dispatch('action名称', 参数) 调用。
this.$store.dispatch('addUser', 2)

 

示例》》》》》》:fetchUser 请求 !!!

// store/index.js
const store = new Vuex.Store({
  state: { user: null },
  mutations: {
    setUser(state, user) {
      state.user = user
    }
  },
  actions: {
    // 异步获取用户信息
    fetchUser({ commit }, userId) {
      // 模拟接口请求
      return new Promise(resolve => {
        setTimeout(() => {
          const user = { id: userId, name: '张三' }
          commit('setUser', user) // 提交 mutation 修改状态
          resolve(user)
        }, 1000)
      })
    }
  }
})

 

在组件中触发:比如登录用户名,密码可以这样,成功获取数据 this.$router.push('/')

<script>
export default {
  mounted() {
    // 触发异步 action
    this.$store.dispatch('fetchUser', 123).then(user => {
      console.log('用户信息:', user)
    })
  }
}
</script>

 

5. Module(模块)

  • 定义:将 store 分割成多个模块(module),每个模块拥有自己的 stategettermutationaction,解决单一状态树过于庞大的问题。

moduleA

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({...})格式注意!!! 没有new
const store = {
  namespaced: true, // 开启命名空间,避免模块间命名冲突
  state: {
    count: 0 // 示例:计数器状态
  },
  getters: {
    getCount(state) {
      return state.count
    }
  },
  mutations: {
    add(state, num) {
      state.count += num
    }
  },
  actions: {
    addUser({ commit }, num) {
      commit('add', num)
    }
  }
}

export default store

 

在store/index.js

  modules: {
    cart: ModuleA, // 注册模块,访问时需加模块名:$store.state.cart.items
    user: ModuleB
  }

 

如果调用模块属性、方法实例:

 

获取值

<div>模块A: {{ $store.state.cart.count }}</div>

 

触发方法:

 this.$store.dispatch('cart/addUser', 2)

 

 

二、Vuex 在组件中的辅助函数

为简化组件中对 Vuex 的使用,Vuex 提供了 4 个辅助函数:mapStatemapGettersmapMutationsmapActions(需从 Vuex 导入)。

computed: {
    ...mapState('cart', ['count']),
    ...mapGetters('cart', ['getCount']),

    countVal() {
      return this.$store.state.count
    }
  },

 

辅助方法方法使用 

  methods: {
    ...mapMutations('cart', ['add']),
    ...mapActions('cart', ['addUser']),
...other

 

====================================================================

撒花~~~实例用户输入用户名、密码登录,成功登录首页逻辑

====================================================================

// 监听路由----再其它页面退出首页,下次登录成功后回到当前页面

  watch: {
    $route: {
      handler: function (route) {
        this.redirect = route.query && route.query.redirect;
      },
      immediate: true,
    },
  },

 

// 登录请求    dispatch

this.$refs.loginForm.validate((valid) => {
  // md5LoginFrom 存放  用户名密码

  this.$store.dispatch("Login", md5LoginFrom) .then(() => {
      this.$router.push({
         path: this.redirect || "/",
       });
   })

})

 

vuex -user模块处理登录请求

actions: {
    // 登录
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim();
      const password = userInfo.password; return new Promise((resolve, reject) => {
        login(username, password)
          .then((res) => {  
            setToken(res.token);
            commit("SET_TOKEN", res.token); 
            resolve();
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
....

 

 Vuex 整合使用

image

 

说明:

modules 各个模块比如:cart, user,shopping....

getters.js 获取各个模块方法

index.js 是store入口

---------------------------

  modules

     --user.js

     --cart.js

 

getters.js

const getters = {
  getCount: (state) => state.count,
  getCartCount: (state) => state.cart.count
}

export default getters

 

store/index.js

/*
 * @Author: congxd
 * @Date: 2025-08-21 10:33:34
 * @LastEditors: congxd
 * @LastEditTime: 2025-08-21 17:49:48
 * @Description:
 */
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import ModuleA from './ModuleA'
import ModuleB from './ModuleB'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0 // 示例:计数器状态
  },
  getters,
  mutations: {
    add(state, num) {
      state.count += num
    }
  },
  actions: {
    addUser({ commit }, num) {
      // this.add(state)
      commit('add', num)
    }
  },
  modules: {
    cart: ModuleA, // 注册模块,访问时需加模块名:$store.state.cart.items
    user: ModuleB
  }
})

export default store

 

// 页面使用 

computed: {
    ...mapState('cart', ['count']),
    ...mapGetters(['getCartCount']),

    countVal() {
      return this.$store.state.count
    },
    getVals() {
      return this.$store.getters.getCartCount
    }
  },
  methods: {
    ...mapMutations('cart', ['add']),
    ...mapActions('cart', ['addUser']),

    countFn() {
      this.$store.dispatch('addUser', 2)
      this.$store.dispatch('cart/addUser', 2)
      // this.$store.commit('add')
    },

 

 Vuex 工作流程

  1. 组件通过 dispatch 触发 Action(处理异步操作)。
  2. Action 执行完成后,通过 commit 触发 Mutation
  3. Mutation 直接修改 State
  4. State 变化后,驱动组件重新渲染(通过 mapState 或 $store.state 关联)。

使用注意事项

  1. Mutation 必须同步:异步操作必须放在 Action 中,否则无法追踪状态变化。
  2. 避免直接修改 State:必须通过 Mutation 修改,确保状态变化可预测。
  3. 命名空间:多模块时务必开启 namespaced: true,避免命名冲突。
  4. 持久化:Vuex 状态在页面刷新后会丢失,需配合 vuex-persistedstate 等插件持久化到 localStorage 或 sessionStorage

何时使用 Vuex?

  • 小型应用:简单的组件通信(props$emit)即可,无需 Vuex。
  • 中大型应用:存在多个组件共享状态、复杂的状态逻辑、需要追踪状态变化时,建议使用 Vuex。

posted on 2025-08-21 18:01  Mc525  阅读(113)  评论(0)    收藏  举报

导航