深入理解 Vuex:从基础到应用场景

news2025/1/21 18:54:49

cover

前言

在之前的文章中,我们已经对 Vue.js 有了一定的了解。今天我们要对Vue官方的状态共享管理器Vuex进行详细讲解,将其基本吃透,目标是面对大多数业务需求;

一、介绍

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 随着 Vue 一同开发,并且是 Vue.js 官方维护的状态管理库。

在 Vue.js 应用程序中,组件之间的通信是通过 props 和事件来实现的,这种方式在组件层级较浅()的情况下可以很好地管理状态,但是随着应用规模的增长,状态的管理会变得复杂和困难。这时候就需要使用 Vuex 来解决状态管理的问题。

Vuex 中包含以下核心概念:

  • State(状态): 即存储在 Vuex 中的数据,它代表了整个应用的状态。
  • Getter(获取器): 用于从状态树state中派生出一些状态,类似于计算属性
  • Mutation(变更): 是唯一允许修改 Vuex 中状态的地方,但是必须是同步函数。
  • Action(动作): 用于提交 mutation,而不是直接变更状态。可以包含任意异步操作。

二、Vuex的适用范围

Vuex 适用于中大型的 Vue.js 应用程序,特别是当应用的状态变得复杂且需要在多个组件之间共享时。它提供了一种集中式管理状态的方式,使得状态管理变得更加可预测和可维护。
Vuex既适用于Vue2,也适用于Vue3;

当应用中包含以下情况时,考虑使用 Vuex:

  • 多个组件需要共享同一状态。
  • 多个视图依赖于同一状态。
  • 有大量的组件需要访问和修改状态。

当应用程序的状态变得较简单或者组件之间的状态传递并不频繁时,可能并不需要使用 Vuex。在这种情况下,可以考虑使用 Vue.js 的局部状态(data)来管理组件的状态。

三、Vuex的主要组成部分

Vuex 的核心包含四个主要部分:StateGettersMutationsActions

1.State

State 是 Vuex 存储数据的地方,它类似于组件中的 data。State 中的数据可以通过 this.$store.state 访问。

①在根Vuex中定义state
state: {
    message: 'Hello, Vuex!', // 字符串类型变量
    count: 0, // 数字类型变量
    isActive: false, // 布尔类型变量
    user: { // 对象类型变量
      name: 'John Doe',
      age: 30
    },
    items: ['apple', 'banana', 'orange'], // 数组类型变量
    currentDate: new Date() // 引用类型变量
  }

②在 Vuex 中定义模块的 state:

// Module A
const moduleA = {
  state: {
    message: 'Hello from Module A',
    count: 0
  }
};

// Module B
const moduleB = {
  state: {
    message: 'Hello from Module B',
    isActive: true
  }
};

// Vuex Store
const store = new Vuex.Store({
  modules: {
    moduleA,
    moduleB
  }
});

在这个示例中,我们定义了两个模块 moduleAmoduleB,每个模块都有自己的 state 对象,包含了不同的状态属性。
以下是两种在组件中使用 Vuex state 的案例:

①根Vuex直接访问 $store.state:
<template>
  <div>
    <p>Message: {{ $store.state.message }}</p>
    <p>Count: {{ $store.state.count }}</p>
    <p>Active: {{ $store.state.isActive }}</p>
    <p>User: {{ $store.state.user.name }} ({{ $store.state.user.age }})</p>
    <p>Items: {{ $store.state.items }}</p>
    <p>Current Date: {{ $store.state.currentDate }}</p>
  </div>
</template>

特点:

  • 直接访问 $store.state 可以在模板中直接使用 Vuex store 中的 state,语法简单直接。
  • 在模板中使用 $store.state 可能会导致代码冗长,难以维护,尤其是在大型应用中。

② 根Vuex使用 mapState 辅助函数:

<template>
  <div>
    <p>Message: {{ message }}</p>
    <p>Count: {{ count }}</p>
    <p>Active: {{ isActive }}</p>
    <p>User: {{ user.name }} ({{ user.age }})</p>
    <p>Items: {{ items }}</p>
    <p>Current Date: {{ currentDate }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState([
      'message',
      'count',
      'isActive',
      'user',
      'items',
      'currentDate'
    ]) // 传入数组
  }
};
</script>

特点:

  • 使用 mapState 可以将 Vuex store 中的 state 映射到组件的计算属性中,使得在模板中可以直接使用这些计算属性,映射在计算属性中才能保证实时响应。
  • 使用 mapState 可以简化模板中对 Vuex state 的访问,提高代码的可读性和可维护性。
  • mapState 需要传入一个数组或对象作为参数,这个参数包含了需要映射的 state 属性,这样可以灵活地选择需要的属性映射到组件中。
③直接访问模块 $store.state
<template>
  <div>
    <p>Message from Module A: {{ $store.state.moduleA.message }}</p>
    <p>Count from Module A: {{ $store.state.moduleA.count }}</p>
    <p>Message from Module B: {{ $store.state.moduleB.message }}</p>
    <p>isActive from Module B: {{ $store.state.moduleB.isActive }}</p>
  </div>
</template>

④模块state使用 mapState 辅助函数

<template>
  <div>
    <p>Message from Module A: {{ moduleA_message }}</p>
    <p>Count from Module A: {{ moduleA_count }}</p>
    <p>Message from Module B: {{ moduleB_message }}</p>
    <p>isActive from Module B: {{ moduleB_isActive }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState('moduleA', [ // 模块名
      'message as moduleA_message', // 使用别名来避免与全局变量冲突
      'count as moduleA_count' // count是原名,moduleA_count是别名
    ]),
    ...mapState('moduleB', [
      'message as moduleB_message',
      'isActive as moduleB_isActive'
    ])
  }
};
</script>
⑤用mapState函数的对象形式映射模块状态

在模板中,你可以直接使用这两个计算属性来获取模块 A 和模块 B 中的 message 状态。下面是模板中如何使用这两个计算属性的示例:

<template>
  <div>
    <p>Message from Module A: {{ moduleA_message }}</p>
    <p>Message from Module B: {{ moduleB_message }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState({
      // 使用命名空间来映射模块中的状态
      moduleA_message: state => state.moduleA.message, // 模块A下的message对象,别名为moduleA_message
      moduleB_message: state => state.moduleB.message // moduleA_message可以用引号括住,也可以不要引号
    })
  }
};
</script>

在这个案例中,我们展示了五种使用 的 state 的方式。基于模块创建的state使用和基于根Vuex的state使用;

2.Getter

①定义

Getter 允许我们在Vuex中派生状态,它类似于组件中的 computed 属性。Getter 可以接收 state 作为参数,然后返回派生出的状态。

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Todo 1', done: true },
      { id: 2, text: 'Todo 2', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done);
    }
  }
});

在 Vuex 中,Getter 可以用来对 store 中的 state 进行一些计算或筛选,从而得到我们想要的状态,而不需要直接修改原始的 state。这样做有几个好处:

  • 组件中的状态派生: Getter 可以用来将 store 中的状态进行处理,然后在组件中直接使用这些派生出的状态,而无需在组件中进行复杂的计算逻辑。
  • 避免直接修改 state: 使用 Getter 可以避免直接修改 store 中的 state,使得代码更加可维护和可测试,同时也保证了 Vuex 的单向数据流。
  • 重用性和可组合性: 可以将 Getter 进行组合和重用,使得代码更加灵活和可扩展。
②组合性和复用性

在上面的示例中,我们定义了一个名为 doneTodosGetter,它接收 store 中的 state 作为参数,然后返回一个数组,这个数组包含了所有已完成的 todo。在组件中可以直接使用 doneTodos 这个 Getter 来获取已完成的 todo,而无需在组件中手动筛选 todo 数组。这样可以使得组件中的代码更加简洁和清晰。
对于第三点的复用性和组合性,案例如下:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Todo 1', done: true },
      { id: 2, text: 'Todo 2', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done);
    },
    undoneTodos: state => {
      return state.todos.filter(todo => !todo.done);
    },
    totalTodosCount: state => {
      return state.todos.length;
    },
    undoneTodosCount: (state, getters) => {
      return getters.doneTodos.length; // undoneTodosCount Getter 使用了 doneTodos Getter 来获取所有已完成的任务
    }
  }
});
③模块间的 Getter 访问

在 Vuex 中,一个模块的 Getter 可以访问其他模块的 state 和 Getter,以及根模块的 state 和 Getter。这是因为在 Getter 中,可以通过参数访问当前模块的 state 和 Getter,以及 rootState 和 rootGetters。同理Vuex根getters也可以访问其他模块的state和getters;案例代码如下:

const store = new Vuex.Store({
  modules: {
    moduleA: {
      state: {
        message: 'Module A Message'
      },
      getters: {
        moduleA_message: state => state.message
      }
    },
    moduleB: {
      state: {
        message: 'Module B Message'
      },
      getters: {
        moduleB_message: state => state.message
      }
    },
    moduleC: {
      getters: {
        combinedMessages: (state, getters, rootState, rootGetters) => {
          const moduleA_message = rootGetters['moduleA/moduleA_message'];
          const moduleB_message = rootGetters['moduleB/moduleB_message'];
          return `${moduleA_message} - ${moduleB_message}`;
        }
      }
    }
  }
});
const store = new Vuex.Store({
  modules: {
    moduleA: {
      state: {
        message: 'Module A Message'
      },
      getters: {
        moduleA_message: state => state.message
      }
    }
  },
  getters: {
    moduleA_message: (state, rootGetters) => {
      return rootGetters['moduleA/moduleA_message'];
    }
  }
});

从这个角度看,rootGetters是一个对象,其中每个键代表每个模块名称,值为每个模块对于的getter
同理rootState.moduleName.stateName可以访问不同模块间的state属性;

④缓存特性

Getter 在默认情况下是具有缓存特性的,意味着在相同的状态下多次调用相同的 Getter,只会计算一次,并且在下次调用时直接返回缓存的结果,而不会重新计算。这可以提高性能,避免重复计算

Vuex 中,Getter 是一个函数,可以接收 stategettersrootState 作为参数。这使得 Getter 具有更大的灵活性, 由于 Getter 是函数,因此可以在其中进行条件判断和计算,根据不同的情况返回不同的值,从而实现更灵活的状态派生和计算逻辑;

3. Mutations

①定义

Mutations 是 Vuex 中用来唯一能修改状态的函数,类似于组件中的 methods。Mutation 函数接收当前状态 (state) 作为第一个参数,并且可以接收额外的参数作为需要修改的数据。Mutation 必须是同步函数,不能包含异步操作。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
    incrementBy(state, payload) {
      state.count += payload.amount;
    }
  }
});
  • Mutations 是同步的:Mutations 中的操作是同步执行的,不支持异步操作。
  • 只能通过 Mutations 修改状态:在 Vuex 中,强制规定只能通过 Mutations 来修改状态,这样可以更好地追踪状态的变化,并且使得状态变更更加可控。
②在组件中使用
methods: {
  increment() {
    this.$store.commit('increment');
  },
  decrement() {
    this.$store.commit('decrement');
  },
  incrementBy(amount) {
    this.$store.commit('incrementBy', { amount }); // this指的是Vue实例,第二个参数等于{ amount: amount }
  }
}
③应用场景
  • 修改单个状态:当需要修改 Vuex 中的某个单个状态时,可以使用 Mutation。
  • 批量修改状态:可以一次性修改多个状态,保持状态变更的原子性。
  • 追踪状态变化:通过 Mutation,可以清晰地追踪状态的变化,便于调试和排查问题。
    下面是应用场景2的一个案例:
const store = new Vuex.Store({
  state: {
    count: 0,
    message: 'Hello, Vuex!'
  },
  mutations: {
    updateState(state, payload) {
      // payload 是一个包含多个状态的对象
      Object.assign(state, payload);
    }
  },
  actions: {
    updateState(context, payload) {
      context.commit('updateState', payload);
    }
  }
});

// 在组件中调用这个 Mutation 来批量修改状态
this.$store.commit('updateState', {  // 如果是模块,则this.$store.commit('moduleName/mutationName', payload)
  count: 10,
  message: 'Hello, Vuex! Updated!'
});

Object.assign(state, payload);是浅拷贝方法,因此组件中这样使用,可能会导致整个模块或者全局都改变!

4. Actions

①定义

Action 类似于 Mutation,但具有异步操作的能力;它提交的是 Mutation,而不是直接变更状态。其通过 store.dispatch 触发Mutations 来变更状态。
Actions 接收一个上下文对象 (context),这个context是包含了与 Vuex 实例具有相同方法和属性的对象,例如 statecommitdispatch 等;

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync(context) {
      setTimeout(() => {
        context.commit('increment'); // 变量名为对应mutation名称
      }, 1000);
    }
  }
});

在 Vuex 中,每个模块module内部都有一个上下文对象 (context),它提供了与 根store 实例具有相同方法和属性的对象,包括 state(属性)、commit(方法,提交mutation)、dispatch(方法,分发action触发异步) 等。这样设计的目的是为了让模块内部的 actions、mutations、getters 等能够访问和操作模块的局部状态,而不需要通过全局的 store 对象。

②组件中使用

Actions 可以通过 store.dispatch 方法在组件中触发。在 Action 中,可以执行异步操作,例如发起 HTTP 请求、定时器等,然后在异步操作完成后提交 Mutations 来变更状态

// 组件中触发 Action
methods: {
  incrementAsync() {
    this.$store.dispatch('incrementAsync');
  }
}
③特点
  • 异步操作:Actions 可以执行任意异步操作,例如 HTTP 请求、定时器等。
  • 提交 Mutations:Actions 通过 context.commit 来提交 Mutations,从而变更状态。
  • 触发方式:Actions 可以通过 store.dispatch 方法在组件中触发。
④应用场景
  • 处理异步逻辑:例如发起 HTTP 请求获取数据后提交 Mutations 更新状态。
  • 封装复杂逻辑:将复杂的业务逻辑封装在 Action 中,使组件更加简洁。
  • 异步操作:Actions 可以执行异步操作,但应该避免在 Action 中进行直接的状态变更。
  • 触发方式:Actions 必须通过 store.dispatch 方法来触发。保证顺序执行和稳定;
⑤WebGIS中的应用场景
  • 异步数据获取: 在 WebGIS 应用中,通常需要从服务器获取地理空间数据、地图瓦片、地图图层配置等信息。Actions 可以用于发起异步请求,并在数据获取完成后更新 Vuex 中的状态,以便在地图中显示数据。
  • 用户交互和事件处理: 用户在地图上的操作通常会触发一系列的事件,例如点击地图、拖动地图、放大缩小地图等。Actions 可以用于监听这些事件,并根据用户的操作进行相应的状态更新或地图操作。
  • 状态管理: WebGIS 应用中通常包含复杂的地图状态,例如地图的视图范围、图层的可见性、图层样式等。Actions 可以用于管理这些状态,并在需要时进行状态的更新和同步。
  • 地图操作和交互效果: Actions 可以用于执行地图操作,例如平移地图、缩放地图、绘制图形等,并根据操作结果更新地图的状态和展示效果。
  • 应用配置和设置: Actions 可以用于处理应用的配置信息和用户设置,例如地图的初始配置、图层的加载顺序、应用的主题设置等。

四、Vuex的常用函数

1.mapState:

mapState 函数用于将 Vuex 中的 state 映射为组件的计算属性。它接收一个数组或对象作为参数,数组中可以是 state 中的属性名,也可以是对象形式,对象的键是组件中的属性名,值是 state 中的属性名或者是一个返回状态的函数。这样,在组件中就可以直接使用这些计算属性,无需再通过 $store.state.xxx 的方式访问 Vuex 中的状态。

import { mapState } from 'vuex';

export default {
  computed: {
    // 使用数组
    ...mapState(['count', 'message']),
    
    // 使用对象
    ...mapState({
      user: state => state.userInfo,
      isLoggedIn: state => state.auth.isLoggedIn
    })
  }
};

2.mapGetters:

mapGetters 函数用于将 Vuex 中的 getters 映射为组件的计算属性。它接收一个数组或对象作为参数,用法与 mapState 相似,可以使用数组形式或者对象形式来进行映射。

import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['doneTodosCount', 'undoneTodosCount']),

    ...mapGetters({
      formattedMessage: 'formattedMessage'
    })
  }
};

3.mapMutations:

mapMutations 函数用于将 Vuex 中的 mutations 映射为组件的方法。它接收一个数组或对象作为参数,数组中是 mutations 中的方法名,对象形式的键是组件中的方法名,值是 mutations 中的方法名。

import { mapMutations } from 'vuex';

export default {
  methods: {
    ...mapMutations(['increment', 'decrement']),

    ...mapMutations({
      setUserName: 'SET_USER_NAME'
    })
  }
};

数组方法直接用,对象方法可以改别名后使用

...mapMutations(['increment', 'decrement']) 等价于以下代码:

{
  increment: function() {
    return this.$store.commit('increment');
  },
  decrement: function() {
    return this.$store.commit('decrement');
  }
}

它将 mapMutations 返回的对象展开,将其中的每个方法映射到组件中,使得用户可以直接调用 this.increment()this.decrement() 来提交对应的 mutations

4.mapActions:

mapActions 函数用于将 Vuex 中的 actions 映射为组件的方法。用法与 mapMutations 类似,接收一个数组或对象作为参数,数组中是 actions 中的方法名,对象形式的键是组件中的方法名,值是 actions 中的方法名。

import { mapActions } from 'vuex';

export default {
  methods: {
    ...mapActions(['login', 'logout']),

    ...mapActions({
      fetchUserData: 'FETCH_USER_DATA'
    })
  }
};

通常情况下,mutation 用于同步地修改状态,而 actions 则用于包含异步操作的场景。在 actions 中可以调用多个 mutation 来修改状态,但通常不会在 actions 中定义不需要通过 mutation 修改状态的独立方法。这样可以保持状态变更的可追踪性和可维护性。

当在 actions 中执行异步操作时,可能需要在异步操作完成后修改多个状态。例如,假设有一个购物车功能,需要在用户点击结账按钮时执行以下操作:

  1. 清空购物车中的商品列表。
  2. 将商品列表中的商品添加到订单列表中。
  3. 将订单总金额清零。

在这种情况下,可以在 actions 中调用多个 mutation 来修改这些状态。以下是示例代码:

const store = new Vuex.Store({
  state: {
    cart: [
      { id: 1, name: 'Product 1', price: 10 },
      { id: 2, name: 'Product 2', price: 20 },
      // 其他商品
    ],
    orders: [],
  },
  getters: {
    totalAmount: state => {
      return state.cart.reduce((total, product) => total + product.price, 0); // 累加,p1为累加器,p2为当前元素,0为初始值
    }
  },
  mutations: {
    clearCart(state) {
      state.cart = [];
    },
    addToOrders(state, products) {
      state.orders.push(...products);
    },
    resetTotalAmount(state) {
      state.totalAmount = 0;
    }
  },
  actions: {
    checkout({ commit, state }) {
      // 模拟异步操作,例如向后端发送订单请求
      setTimeout(() => {
        // 异步操作完成后,调用多个 mutation 来修改状态
        commit('addToOrders', state.cart); // 添加到订单
        commit('clearCart'); // 清空购物车
        commit('resetTotalAmount'); //清空总额
      }, 1000);
    }
  }
});

在上面的示例中,checkout action 执行了一系列异步操作,然后调用了多个 mutation 来修改状态。

五、Vuex的应用场景

1.管理购物车状态:

  • 应用场景:在线商城中,用户可以将商品加入购物车,修改商品数量或移除商品。
  • 实现方式:使用 Vuex 来管理购物车的状态,包括购物车中的商品列表、商品数量、总价等信息。通过 mutations 修改购物车状态,例如增加商品、删除商品、修改商品数量等操作。

2.用户认证状态管理:

  • 应用场景:网站或应用中需要对用户进行认证,登录后可以访问特定的页面或功能,未登录状态下需要跳转到登录页面。
  • 实现方式:使用 Vuex 存储用户的认证状态,例如用户信息、登录状态、权限等信息。通过 mutations 修改用户认证状态,例如登录、注销、更新用户信息等操作。在需要认证的页面或功能中,通过 getters 获取用户的认证状态来控制页面展示逻辑。

3.表单数据管理:

  • 应用场景:页面中存在复杂的表单,包含多个输入框、复选框、下拉框等元素,需要实时根据用户输入更新表单数据。
  • 实现方式:使用 Vuex 存储表单的状态,例如表单数据、验证状态、提交状态等信息。通过 mutations 修改表单数据状态,例如更新输入框值、切换复选框状态等操作。通过 getters 获取表单数据状态,实时展示给用户,同时通过 actions 处理表单提交逻辑,例如表单验证、数据提交等操作。

4.页面之间共享的数据状态:

  • 应用场景:不同页面或组件之间需要共享相同的数据状态,例如全局的主题设置、语言设置等。
  • 实现方式:使用 Vuex 存储全局的数据状态,例如主题颜色、语言设置等信息。通过 mutations 修改全局数据状态,例如切换主题、切换语言等操作。通过 getters 获取全局数据状态,实时应用到页面或组件中。

5.WebGIS中的应用场景

在 WebGIS 中,Vuex 可以应用于许多场景,以管理地图状态、图层数据、用户交互等。以下是一些常见的 WebGIS 应用场景:

1.地图状态管理:
  • 应用场景:在 WebGIS 应用中,用户可能会对地图进行缩放、平移、旋转等操作,这些操作会导致地图状态的变化,如当前的中心点、缩放级别、旋转角度等。
  • 实现方式:使用 Vuex 存储地图的状态信息,例如中心点坐标、缩放级别、旋转角度等。通过 mutations 修改地图状态,例如更新中心点坐标、修改缩放级别等操作。通过 getters 获取地图状态信息,以便在地图组件中实时展示。
2.图层数据管理:
  • 应用场景:WebGIS 应用中通常包含多个图层,如矢量图层、栅格图层、图像图层等,这些图层可能需要根据用户的操作进行显示、隐藏、更新等操作。
  • 实现方式:使用 Vuex 存储图层的状态信息,例如图层的可见性、透明度、样式等。通过 mutations 修改图层状态,例如显示/隐藏图层、更新图层样式等操作。通过 getters 获取图层状态信息,以便在地图组件中实时控制图层的显示。
3.用户交互管理:
  • 应用场景:WebGIS 应用中用户可能会进行交互操作,如点击地图、绘制要素、查询信息等,这些操作需要及时响应并更新相关状态。
  • 实现方式:使用 Vuex 存储用户交互的状态信息,例如点击的位置、绘制的要素、查询到的信息等。通过 mutations 修改用户交互状态,例如记录点击位置、绘制要素、查询结果等操作。通过 getters 获取用户交互状态信息,以便在地图组件中实时展示用户的操作。

六、Vuex的最佳实践思路

针对一个中大型WebGIS项目,可以采用以下方法论来设计和组织 Vuex 的解决方案:

  1. 模块化设计
    ○ 将 Vuex store 拆分成多个模块,每个模块专注于处理特定的业务逻辑或状态管理。
    ○ 根据业务领域的不同,可以将模块划分为地图模块、用户模块、数据模块等,每个模块管理对应领域的状态和逻辑。
  2. 命名空间
    ○ 在定义 Vuex 模块时,可以使用命名空间来避免不同模块之间的命名冲突,确保模块的状态和操作的唯一性和可识别性。
    ○ 通过在模块定义时设置 namespaced: true 来启用命名空间。
  3. 拆分状态
    ○ 将 Vuex store 中的状态拆分成不同的模块级别的状态,每个模块负责管理自己的状态。
    ○ 例如,地图模块可以管理地图状态(中心点坐标、缩放级别等)、图层状态等,用户模块可以管理用户信息、权限状态等。
  4. 常量管理
    ○ 使用常量来表示 mutation 和 action 的名称,以提高代码的可读性和维护性。
    ○ 将常量集中管理,可以在单独的文件中定义常量,并在需要使用的地方引入,避免重复定义和错误拼写。
  5. 异步操作
    ○ 对于需要进行异步操作的情况,例如 API 请求、数据加载等,使用异步 action 来处理。
    ○ 在异步 action 中进行异步操作,并在操作完成后提交 mutation 来更新状态,保持 Vuex 单向数据流的规范。
  6. 模块间通信
    ○ 对于模块之间需要进行通信的情况,可以通过根模块来协调不同模块之间的状态和操作。
    ○ 使用根模块的 state 和 getters 来访问和管理不同模块的状态,使用根模块的 mutations 和 actions 来触发和处理模块间的操作。
  7. 代码组织
    ○ 合理组织 Vuex 相关的代码结构,例如将常量、mutations、actions、getters 等分别放置在不同的文件中,便于管理和维护。
    ○ 可以按照功能模块或业务领域来组织代码结构,使代码清晰易读。

七、总结

在本文中,我们全面地探讨了 Vuex,这是一个专为 Vue.js 应用程序开发的状态管理模式。通过学习 Vuex 的基础概念、高级用法、辅助函数和应用场景,我们深入理解了 Vuex 的工作原理和应用方法。

通Vuex 提供了一种统一的状态管理方案,使得不同组件之间可以轻松共享状态,并且保证状态的一致性。
在实际项目中,我们可以利用 Vuex 来管理购物车状态、用户认证状态、表单数据状态等。通过合理地设计和使用 Vuex,我们可以有效地管理复杂的状态逻辑,并且提高项目的开发效率和质量。

文章参考

  • 开始 | Vuex:

  • vuex的超详细讲解和具体使用细节记录(篇幅略长,建议收藏) - 知乎

  • Vuex的全面简约版总结_vuex参考文献-CSDN博客

项目地址

  • Github地址
  • 拓展阅读

如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1495732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rust入门:GCC或VS2019中的c或c++程序如何调用Rust静态库

首先创建一个rust的库&#xff0c;这里我假设命名为c-to-rust1 cargo new --lib c-to-rust1 其中&#xff0c;src/lib.rs的内容如下&#xff0c; #[no_mangle] pub extern "C" fn get_string() -> *const u8 {b"Hello C World\0".as_ptr() }注解 …

高分辨率全球海洋温度和盐度再分析数据Global Ocean Physics Reanalysis(0.083°),并利用matlab读取绘图

1.引言 在研究全球海平面变化的问题中&#xff0c;卫星测高获得总的海平面变化&#xff0c;而海平面变化包含质量变化和比容变化。因此测高数据和海洋物理分析数据对于海平面研究至关重要。 测高数据下载网址&#xff1a; Global Ocean Gridded L 4 Sea Surface Heights And …

【深度学习笔记】计算机视觉——FCN(全卷积网络

全卷积网络 sec_fcn 如 :numref:sec_semantic_segmentation中所介绍的那样&#xff0c;语义分割是对图像中的每个像素分类。 全卷积网络&#xff08;fully convolutional network&#xff0c;FCN&#xff09;采用卷积神经网络实现了从图像像素到像素类别的变换 :cite:Long.Sh…

Docker数据卷的挂载

目录 1 概念 2 常用命令 3 操作步骤(主要讲在创建容器时的挂载) 3.1 挂载在默认目录 3.2 挂载在自定义目录 4 附加内容(查看容器的挂载情况) 1 概念 数据卷&#xff08;volume&#xff09;是一个虚拟目录&#xff0c;是容器内目录与宿主机目录之间映射的桥梁。这样容器内…

如何恢复已删除的华为手机图片?5 种方式分享

不幸的现实是&#xff0c;华为的珍贵时刻有时会因为意外删除、软件故障或其他不可预见的情况而在眨眼之间消失。在这种情况下&#xff0c;寻求恢复已删除的图片成为个人迫切关心的问题。 本文旨在为用户提供如何从华为恢复已删除图片的实用解决方案。我们将探索五种可行的方法…

#微信小程序创建(获取onenet平台数据)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a;创建一个小程序&#xff08;http get获取onenet平台数据&#xff09; 3.记录&#xff1a; 百度网盘链接&#xff1a;https://pan.baidu.com/s/1eOd-2EnilnhPWoGUMj0fzw 提取码: 2023 &#xff08;1&#xff09;新建一个工…

CentOS/Fedora/Ubuntu/Debian 系统 wget 命令

wget 是云服务器安装环境和面板常用下载命令。下载软件或从远程服务器下载备份到本地服务器&#xff0c;也可以使用 wget 把文件下载到云服务器上。 VPS wget 命令最常用使用方法如下&#xff1a; 安装 wget 一般来说 wget 命令是系统自带的&#xff0c;方面安装环境和面板&…

LVS----DR模式

一、LVS-DR工作原理 1、LVS-DR数据包流向分析 客户端发送请求到Director Server (负载均衡器)&#xff0c;请求的数据报文&#xff08;源IP是CIP&#xff0c;目标IP是VIP&#xff09;到达内核空间。Director Server 和Real Server 在同一个网络中&#xff0c;数据通过二层数据…

guava的使用

对数组操作前判断是否会越界&#xff1a; List<String> s new ArrayList<>();System.out.println(Preconditions.checkElementIndex(2,s.size(),"下标长度超过了")); 是否为空 String s null;System.out.println(Preconditions.checkNotNull(s)); 判空…

六自由度Stewart平台的matlab模拟与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1运动学原理 4.2 Stewart平台运动学方程 5.完整工程文件 1.课题概述 六自由度Stewart平台的matlab模拟与仿真&#xff0c;模拟六自由度Stewart平台的动态变化情况以及伺服角度。 2.系统仿真结果 3.核…

设置word目录从正文开始记录页码,并解决word目录正常,但正文页脚处只显示第一页的页码

设置word目录从正文开始记录页码&#xff0c;并解决word目录正常&#xff0c;但正文页脚处只显示第一页的页码 问题详情1&#xff1a;如何设置目录从正文开始记录页码 问题详情2&#xff1a;word目录处的页码正常&#xff0c;但正文只有第一页的页脚处显示页码 解决方法 在设置…

SpringCloud微服务-RabbitMQ快速入门

文章目录 RabbitMQ快速入门1、什么是MQ&#xff1f;2、RabbitMQ概述3、RabbitMQ的结构和概念4、常见消息模型5、HelloWorld RabbitMQ快速入门 1、什么是MQ&#xff1f; MQ &#xff08;MessageQueue&#xff09;&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的…

【❤️算法笔记❤️】-每日一刷-21、合并两个有序链表

文章目录 题目思路解答 题目 简单 相关标签 相关企业 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入…

蓝桥杯-排序

数组排序 Arrays.sort(int[] a) 这种形式是对一个数组的所有元素进行排序&#xff0c;并且时按从小到大的顺序。 package Work;import java.util.*;public class Imcomplete {public static void main(String args[]) {int arr[]new int [] {1,324,4,5,7,2};Arrays.sort(arr)…

【Java】CAP理论以及它的实际应用案例

目录 简介 不是所谓的“3 选 2” CAP 实际应用案例 总结 CAP 理论/定理起源于 2000年&#xff0c;由加州大学伯克利分校的Eric Brewer教授在分布式计算原理研讨会&#xff08;PODC&#xff09;上提出&#xff0c;因此 CAP定理又被称作 布鲁尔定理&#xff08;Brewer’s the…

JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)

目录 项目主要目标 技术选型 面向对象编程 使用集合容器 程序流程控制 使用常见API 系统架构搭建与欢迎页设计 Account ATM Test 用户开户功能实现 录入账户名称与性别 录入账户密码与取现额度 生成新卡号 存入账户 登录功能实现 登录后操作实现 退出账户 存…

JavaScript 入门手册(二)

目录 八、JavaScript 数据类型 8.1 动态类型 8.2 typeof 操作符 8.3 Undefined 和 Null 九、JavaScript 对象 9.1 创建对象 9.2 对象方法 十、作用域 十一、条件语句 十二、循环 12.1 for 循环 12.1.1 语句 1 12.1.2 语句 2 12.1.3 语句 3 12.2 for...in 循环 …

文本溢出隐藏 显示省略号,鼠标悬浮展示 el-tooltip(TooltipIsShowMixin封装)

目录 mixins 封装使用 TooltipIsShowMixin效果展示 mixins 封装 TooltipIsShowMixin.js export const TooltipIsShowMixin {data() {return {tooltipIsShow: false}},methods: {tooltipIsDisHandler(className) {this.$nextTick(() > {const dom document.querySelector…

语义化与自动化——第三代指标平台两大核心能力详解(内含QA)

【作者简介】杜雪芳&#xff0c;Aloudata 合伙人兼首席业务架构师。12 年数据业务从业经验&#xff0c;3 年管理咨询经验。历任阿里集团淘宝商业分析负责人、阿里音乐商业智能中心负责人、蚂蚁集团用户增长分析与洞察产品负责人。在数据体系搭建、数据分析、用户标签建设、用户…

混合动力汽车应用中的厚膜电阻器

电阻器在标准内燃机汽车的许多应用中都有发现。混合动力汽车中的电阻器在电池管理&#xff08;BMS&#xff09;和动态制动系统中也有其他应用。 混合动力汽车使用两种不同的能源来最大限度地提高效率。这通常意味着将存储在电池中的电能与内燃机&#xff08;AutoExpress&#x…