Pinia/Vuex 4的状态管理集成：State的响应性Proxy封装与Mutation/Action的调度

admin
Sat, 29 Nov 2025 05:22:21 +0000
Vue, pinia, state, vuex

Pinia/Vuex 4 的状态管理集成：State 的响应式 Proxy 封装与 Mutation/Action 的调度 大家好，今天我们深入探讨 Pinia 和 Vuex 4 这两个流行的 Vue.js 状态管理库的核心机制，重点关注它们如何利用 Proxy 实现 State 的响应式封装，以及如何调度 Mutation 和 Action 来修改 State。我们将通过代码示例和逻辑分析，帮助大家理解这些概念，并能在实际项目中更好地运用它们。 1. 状态管理库的核心概念 在深入具体实现之前，我们先回顾一下状态管理库的一些核心概念： State (状态)：应用程序的数据源，存储应用的所有数据。 Getter (获取器)：从 State 派生出的计算属性，用于获取和格式化 State 中的数据。 Mutation (变更)：同步修改 State 的唯一方式。 Action (动作)：提交 Mutation 的方式，可以包含异步操作。 Store (仓库)：包含 State、Getter、Mutation 和 Action 的集合。 2. Vuex 4 的响应式 State 封装 Vue …

继续阅读“Pinia/Vuex 4的状态管理集成：State的响应性Proxy封装与Mutation/Action的调度”

The post Pinia/Vuex 4的状态管理集成：State的响应性Proxy封装与Mutation/Action的调度 first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

Pinia/Vuex 4 的状态管理集成：State 的响应式 Proxy 封装与 Mutation/Action 的调度

大家好，今天我们深入探讨 Pinia 和 Vuex 4 这两个流行的 Vue.js 状态管理库的核心机制，重点关注它们如何利用 Proxy 实现 State 的响应式封装，以及如何调度 Mutation 和 Action 来修改 State。我们将通过代码示例和逻辑分析，帮助大家理解这些概念，并能在实际项目中更好地运用它们。

1. 状态管理库的核心概念

在深入具体实现之前，我们先回顾一下状态管理库的一些核心概念：

State (状态)：应用程序的数据源，存储应用的所有数据。

Getter (获取器)：从 State 派生出的计算属性，用于获取和格式化 State 中的数据。

Mutation (变更)：同步修改 State 的唯一方式。

Action (动作)：提交 Mutation 的方式，可以包含异步操作。

Store (仓库)：包含 State、Getter、Mutation 和 Action 的集合。

2. Vuex 4 的响应式 State 封装

Vuex 4 依赖于 Vue 3 的响应式系统。在 Vue 3 中，reactive 函数用于创建对象的响应式代理。Vuex 4 的 State 就是通过 reactive 函数进行封装的。

2.1 reactive 函数

reactive 函数接受一个普通 JavaScript 对象作为参数，并返回一个 Proxy 对象。当访问或修改 Proxy 对象的属性时，会触发相应的 get 和 set 拦截器。这些拦截器负责通知 Vue 的依赖追踪系统，从而实现响应式更新。

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  message: 'Hello Vuex'
});

console.log(state.count); // 访问属性，触发 get 拦截器

state.count++; // 修改属性，触发 set 拦截器

console.log(state.count);

2.2 Vuex 4 中的 State 封装

在 Vuex 4 中，State 被封装在 store._state 属性中。这个 _state 属性是通过 reactive 函数创建的 Proxy 对象。

import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0,
      message: 'Hello Vuex'
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

console.log(store.state.count); // 访问 store.state.count，触发 get 拦截器

store.commit('increment'); // 提交 mutation，修改 store.state.count，触发 set 拦截器

console.log(store.state.count);

2.3 Vuex 4 的响应式原理

当组件访问 store.state.count 时，Vue 的依赖追踪系统会将该组件标记为依赖 store.state.count。当 store.state.count 的值发生变化时，Vue 会自动更新依赖于该值的组件。这就是 Vuex 4 实现响应式的基本原理。

3. Pinia 的响应式 State 封装

Pinia 也利用了 Vue 3 的响应式系统，但它并没有像 Vuex 4 那样使用 reactive 函数直接封装整个 State 对象。Pinia 使用 ref 和 computed 来定义 State 和 Getter。

3.1 ref 和 computed 函数

ref 函数用于创建响应式的引用。ref 函数接受一个初始值作为参数，并返回一个包含 value 属性的对象。访问或修改 value 属性会触发相应的 get 和 set 拦截器。

computed 函数用于创建基于其他响应式值的计算属性。computed 函数接受一个 getter 函数作为参数，并返回一个包含 value 属性的对象。value 属性的值是 getter 函数的返回值。当 getter 函数依赖的响应式值发生变化时，value 属性的值会自动更新。

import { ref, computed } from 'vue';

const count = ref(0);
const message = ref('Hello Pinia');

const doubledCount = computed(() => count.value * 2);

console.log(count.value); // 访问 count.value，触发 get 拦截器

count.value++; // 修改 count.value，触发 set 拦截器

console.log(count.value);
console.log(doubledCount.value); // 访问 doubledCount.value，触发 get 拦截器

3.2 Pinia 中的 State 封装

在 Pinia 中，State 通常使用 ref 函数定义。

import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);
  const message = ref('Hello Pinia');

  function increment() {
    count.value++;
  }

  return { count, message, increment };
});

//使用
import { useCounterStore } from './stores/counter';
import { storeToRefs } from 'pinia';
import { computed } from 'vue';

export default {
  setup() {
    const counterStore = useCounterStore();
    const { count, message } = storeToRefs(counterStore); // 使用 storeToRefs 解构响应式变量
    const doubledCount = computed(() => count.value * 2);

    return {
      count,
      message,
      doubledCount,
      increment: counterStore.increment
    };
  },
  template: `
Count: {{ count }}
Doubled Count: {{ doubledCount }}
Message: {{ message }}
Increment
  `
};

3.3 Pinia 的响应式原理

Pinia 的响应式原理与 Vue 3 的响应式原理相同。当组件访问 count.value 或 message.value 时，Vue 的依赖追踪系统会将该组件标记为依赖这些值。当这些值发生变化时，Vue 会自动更新依赖于这些值的组件。Pinia 通过 storeToRefs API 使得 store 中的 ref 变为组件中直接可以使用的响应式变量，避免了在模板中始终使用 .value 的写法。

4. Mutation 和 Action 的调度

Mutation 和 Action 是修改 State 的两种方式。Mutation 必须是同步的，而 Action 可以包含异步操作。

4.1 Vuex 4 的 Mutation 和 Action 调度

在 Vuex 4 中，Mutation 通过 commit 方法调度，Action 通过 dispatch 方法调度。

import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync(context) {
      setTimeout(() => {
        context.commit('increment');
      }, 1000);
    }
  }
});

store.commit('increment'); // 同步提交 mutation

store.dispatch('incrementAsync'); // 异步提交 action

4.1.1 commit 方法

commit 方法接受一个 Mutation 类型作为参数，并调用相应的 Mutation 函数。Mutation 函数接受 State 作为第一个参数。

store.commit('increment'); // 提交 'increment' mutation

4.1.2 dispatch 方法

dispatch 方法接受一个 Action 类型作为参数，并调用相应的 Action 函数。Action 函数接受一个包含 state、commit、dispatch、getters 和 rootState 的 context 对象作为第一个参数。

store.dispatch('incrementAsync'); // 提交 'incrementAsync' action

4.2 Pinia 的 Action 调度

在 Pinia 中，Action 就是普通的函数，可以直接调用。Pinia 没有像 Vuex 4 那样区分 Mutation 和 Action。所有的状态修改都在 Action 中进行。

import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);

  function increment() {
    count.value++;
  }

  async function incrementAsync() {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    count.value++;
  }

  return { count, increment, incrementAsync };
});

//使用
import { useCounterStore } from './stores/counter';

export default {
  setup() {
    const counterStore = useCounterStore();

    return {
      count: counterStore.count,
      increment: counterStore.increment,
      incrementAsync: counterStore.incrementAsync
    };
  },
  template: `
Count: {{ count }}
Increment
Increment Async
  `
};

4.2.1 直接调用 Action

在 Pinia 中，Action 就是普通的函数，可以直接调用。

const counterStore = useCounterStore();
counterStore.increment(); // 直接调用 increment action
counterStore.incrementAsync(); // 直接调用 incrementAsync action

5. Vuex 4 和 Pinia 的差异比较

特性 | Vuex 4 | Pinia
State 封装 | reactive 函数封装整个 State 对象 | ref 函数封装 State 中的每个属性
Mutation | 必须是同步的，通过 commit 方法调度 | 没有 Mutation 的概念，所有状态修改都在 Action 中进行
Action | 可以包含异步操作，通过 dispatch 方法调度 | 就是普通的函数，可以直接调用
模块化 | 通过 modules 选项实现模块化 | 通过多个 Store 实现模块化
TypeScript 支持 | 需要额外的类型定义文件才能获得更好的类型支持 | 原生支持 TypeScript，类型推断更强大
代码体积 | 相对较大 | 相对较小

6. 代码示例：一个简单的计数器

下面是一个使用 Vuex 4 和 Pinia 实现的简单计数器示例。

6.1 Vuex 4 示例



Count: {{ count }}
Increment
Increment Async




import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['increment', 'incrementAsync'])
  }
};


// store.js
import { createStore } from 'vuex';

export default createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    },
    incrementAsync(context) {
      setTimeout(() => {
        context.commit('increment');
      }, 1000);
    }
  }
});

6.2 Pinia 示例



Count: {{ count }}
Increment
Increment Async




import { useCounterStore } from './stores/counter';
import { storeToRefs } from 'pinia';

export default {
  setup() {
    const counterStore = useCounterStore();
    const { count } = storeToRefs(counterStore); // 解构为响应式变量

    return {
      count,
      increment: counterStore.increment,
      incrementAsync: counterStore.incrementAsync
    };
  }
};


// stores/counter.js
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);

  function increment() {
    count.value++;
  }

  async function incrementAsync() {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    count.value++;
  }

  return { count, increment, incrementAsync };
});

7. 选择合适的库

Vuex 4 和 Pinia 都是优秀的状态管理库，选择哪个取决于项目的具体需求。

Vuex 4：适合大型、复杂项目，需要更严格的状态管理规范。

Pinia：适合中小型项目，或者需要更灵活、更简洁的状态管理方案。

8. 总结：响应式状态管理和状态变更的调度

我们深入探讨了 Pinia 和 Vuex 4 的状态管理机制，核心在于利用 Vue 3 的响应式系统封装 State，并提供不同的方式来调度状态变更。 Vuex 4 区分 Mutation 和 Action，提供更严格的状态管理规范，而 Pinia 则更加简洁灵活，所有状态修改都在 Action 中进行。选择哪个库取决于项目的具体需求。

希望今天的分享能够帮助大家更好地理解 Pinia 和 Vuex 4，并在实际项目中灵活运用它们。谢谢大家！

更多IT精英技术系列讲座，到智猿学院