前端学习12 pinia 和 vuex 状态管理
在现代前端开发中,状态管理是一个至关重要的方面。尤其是在大型应用中,如何高效、清晰地管理状态不仅影响着代码的可读性和可维护性,还对应用的性能有直接的影响。在 Vue3 中,Vuex 和 Pinia 是两种主要的状态管理库,这两者各有不同的设计理念和使用方式。
1.vuex
Vuex 是 Vue.js 官方的状态管理库。它采用了 Flux 的思想,提供了一个集中式存储,允许组件以不同的方式共享状态。Vuex 的核心概念包括 State、Getters、Mutations 和 Actions。
其中:
1.State: 应用的状态存储。
2.Getters: 类似于计算属性,用于计算基于状态的派生状态。
3.Mutations: 处理状态的唯一方式,直接修改状态。
4.Actions: 进行异步操作,并提交 Mutations。
5.modules:进行划分模块。
vuex示例代码:
// store.js
import { createStore } from 'vuex';
const store = createStore({
  state: {
    //状态的存储
    count: 0,
  },
  getters: {
    //计算其中的派生元素
    doubleCount(state) {
      return state.count * 2;
    },
  },
  mutations: {
    //定义其中的操作
    increment(state) {
      state.count++;
    },
  },
  actions: {
    //进行异步操作,并提交 Mutations。
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    },
  },
});
export default store;
使用vuex:
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount']),
  },
  methods: {
    ...mapActions(['increment', 'incrementAsync']),
  },
};
</script>
2.pinia
Pinia 是一个新兴的状态管理库,也是 Vue.js 的官方推荐替代方案。它为 Vue 3 提供了一种更简单、更具灵活性的状态管理方式,与 Vuex 相比,Pinia 在设计上更现代化,支持 Composition API,使得开发者在使用时更加方便。
其中:
Store: 状态存储的基本单位,通过建立一个或多个 Store 来管理状态。这是与vuex最主要的区别。
State: 用于保存应用的响应式状态。
Getters: 计算属性的延伸,基于状态计算派生值。
Actions: 包含了执行异步操作的行为和直接修改状态的方法。
3.pinia的使用
3.1 piniad的创建
import { createApp,h } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
3.2 pinia 定义store
在深入研究核心概念之前,我们需要知道 Pinia 是使用 defineStore() 定义的,并且它需要一个唯一的 name 作为第一个参数传递: name(也称为id)是必需的,Pinia使用 name 参数将 Store 连接到 devtools。
将返回的函数命名为 use… 是一种跨组件的约定,使其用法规范化。
defineStore(name,options)
- name: 必传,类型
string - options:{}
 
import { defineStore } from 'pinia'
// useStore可以是任何类似useUser、useCart的东西
// 第一个参数是应用程序中 Store 的唯一id
export const useStore = defineStore('main', {
  // state: () => ({ count: 0 }),
  state:()=>{
    return {
      // 所有这些属性都将自动推断其数据类型
      items: [],
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  },
  getters: {
    doubleCount: (state) => state.counter * 2,
    //doubleCount(state){
    //  console.log(this,'想要在getter中获取该store的其他内容则不能用箭头函数,')
    //  return state.counter * 2
    //},
  },
  actions: {
    increment(num,test1,test2) {
      console.log(num,test1,test2)
      this.counter++
    },
    randomizeCounter() {
      this.counter = Math.round(100 * Math.random())
    },
  }
})
3.3 使用 Store
我们之所以声明store,是因为在setup()内部调用useStore()之前不会创建存储。
<template>
  <p>Double count is {{ store.doubleCount }}</p>
</template>
<script>
import { mapState } from 'pinia'
import { useStore} from '@/stores/counter'
export default {
  setup() {
    const store = useStore()
    store.counter++
    store.$patch({ // 除了直接用store.counter++改变store之外,您还可以调用该$patch方法。state它允许您对部分对象同时应用多个更改:
      counter: store.counter + 1,
      name: 'Abalam',
    })
 
    store.$patch((state) => { // $patch 方法还接受一个函数,用于应对复杂数据的修改过程
      state.items.push({ name: 'shoes', quantity: 1 })
      state.isAdmin = false
    })
 
    store.increment(9,'测试多参数1','测试2') // 调用 actions 并传入参数
    store.randomizeCounter() // 调用 actions
    return {
      // 您可以返回整个store实例以在模板中使用它
      store,
    }
  },
  computed: { 
    storeCounter() {
      return this.store.counter * 3
    },
    // ...mapState(useCounterStore, ['counter']) // 没有 setup 的时候才使用这方式
  },
}
</script>
4.Vuex vs Pinia
现在我们来比较 Vuex 和 Pinia 的优缺点。
4.1 API 和易用性
Vuex:
采用认证的 Flux 风格,有一定的学习曲线,需要掌握多个概念(状态、getter、mutation、action)。对于小型应用来说,可能会显得过于复杂。
Pinia:
设计更为简单,结合了 Composition API,让开发者能够更直观地管理状态。尤其是 Vue 3 的 Setup 语法糖,使用更加直观。
4.2 响应式
Vuex: 响应式总是要依赖于 Vue 的响应式系统,并且有多种约定(例如 Mutation),使用中需要更小心。
Pinia:
完全基于 Vue 3 的响应式系统,状态变化后组件自动更新,无需额外的处理。
#前端学习#
