vue3如何处理全局状态

151 阅读2分钟

vue3如何处理全局状态

在 Vue 3 中,处理全局状态有多种方式,以下是几种常见的方法:

  1. 使用 provideinject
  • provideinject 是 Vue 3 提供的一种依赖注入机制,适合在组件树中共享状态。

  • 在根组件中使用 provide 提供全局状态,在子组件中使用 inject 注入状态。

<!-- 根组件 App.vue -->
<script setup>
import { provide, ref } from 'vue';

// 提供全局状态
const globalState = ref('初始状态');
provide('globalState', globalState);
</script>

<template>
  <ChildComponent />
</template>
<!-- 子组件 ChildComponent.vue -->
<script setup>
import { inject } from 'vue';

// 注入全局状态
const globalState = inject('globalState');
</script>

<template>
  <div>{{ globalState }}</div>
</template>
  1. 使用 Vuex
  • Vuex 是 Vue 官方推荐的状态管理库,适合管理复杂的全局状态。

  • 首先安装 Vuex:

npm install vuex@next
  • 创建 Vuex store:
// store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment');
    }
  }
});
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

const app = createApp(App);
app.use(store);
app.mount('#app');
<!-- 组件中使用 Vuex -->
<script setup>
import { useStore } from 'vuex';

const store = useStore();
const count = computed(() => store.state.count);

function increment() {
  store.dispatch('increment');
}
</script>

<template>
  <div>{{ count }}</div>
  <button @click="increment">增加</button>
</template>
  1. 使用 reactiveref 创建全局状态
  • 你可以直接使用 reactiveref 创建一个全局状态对象,然后在组件中引入和使用。
// globalState.js
import { reactive } from 'vue';

export const globalState = reactive({
  count: 0
});
<!-- 组件中使用全局状态 -->
<script setup>
import { globalState } from './globalState';

function increment() {
  globalState.count++;
}
</script>

<template>
  <div>{{ globalState.count }}</div>
  <button @click="increment">增加</button>
</template>
  1. 使用 Pinia
  • Pinia 是 Vue 3 的另一个状态管理库,比 Vuex 更轻量且易于使用。

  • 首先安装 Pinia:

npm install pinia
  • 创建 Pinia store:
// stores/counter.js
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++;
    }
  }
});
// main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

const app = createApp(App);
app.use(createPinia());
app.mount('#app');
<!-- 组件中使用 Pinia -->
<script setup>
import { useCounterStore } from './stores/counter';

const counterStore = useCounterStore();
</script>

<template>
  <div>{{ counterStore.count }}</div>
  <button @click="counterStore.increment">增加</button>
</template>

总结

  • provideinject:适合简单的全局状态共享。

  • Vuex:适合复杂的状态管理,但需要额外的配置。

  • reactiveref:适合轻量级的全局状态管理。

  • Pinia:比 Vuex 更轻量,推荐用于新项目。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github