当前位置: 首页 > article >正文

浅谈vuex和pinia的区别

文章目录

  • 介绍
  • 核心概念
  • 用法区别
    • 导入
    • state
    • getters
    • Mutations
    • Actions
  • 工作原理
  • 优缺点

本篇文章主要展示vuex和pinia的区别,详情使用请看博主其他文章或者官方文档

vuex官网:https://vuex.vuejs.org/zh/guide/
pinia官网:https://pinia.vuejs.org/zh/introduction.html

介绍

VueX:VueX 是 Vue.js 官方提供的状态管理库。它基于 Flux 架构模式,提供了一个中央状态存储器来管理应用程序中的状态。VueX 可以通过 mutations、actions 和 getters 等概念来修改和处理状态的变更,同时具有强大的工具和插件支持。

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:

  • Devtools 支持
  • 追踪 actions、mutations 的时间线
  • 在组件中展示它们所用到的 Store
  • 让调试更容易的 Time travel
  • 热更新
  • 不必重载页面即可修改 Store
  • 开发时可保持当前的 State
  • 插件:可通过插件扩展 Pinia 功能
  • 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能。
  • 支持服务端渲染

核心概念

vuex:State,Getter,Mutation,Action,Module
pinia:State,Getter,Action,store

显而易见,pinia去除了Mutation

用法区别

导入

vuex

//store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

pinia

//main.js
import { createPinia } from 'pinia';
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');


// store.js
import { defineStore } from 'pinia';

state

vuex

const store = new Vuex.Store({
  state: {
    count: 0
  }})

组件中使用
直接使用:

<template>
  <p>{{ $store.state.count }}</p>
</template>

通过映射

import { mapState} from 'vuex';

export default {
  computed: {
    ...mapState(['count'])
  }}

pinia

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    name: 'Pinia'
  }),})

组件中简单使用

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
    <p>name: {{ counterStore.name }}</p>
  </div>
</template>

<script setup>
import { useCounterStore } from '@/stores/counter';
const counterStore = useCounterStore();
</script>

getters

vuex

const store = new Vuex.Store({
  getters: {
    doubleCount: state => state.count * 2
  }
});

组件中使用
简单使用

$store.getters.doubleCount

使用映射

import { mapGetters} from 'vuex';
  computed: {
    ...mapGetters(['doubleCount'])
  },

pinia

store.js
export const useCounterStore = defineStore('counter', {
  getters: {
    doubleCount: (state) => state.count * 2
  },})

在组件中使用

<template>
  <div>
    <p>Double Count: {{ counterStore.doubleCount }}</p>
  </div>
</template>

<script setup>
import { useCounterStore } from '@/stores/counter';
const counterStore = useCounterStore();
</script>

Mutations

mutations 是唯一能够直接修改 state 的方法,Vuex 强制要求使用同步函数来更改状态。每个 mutation 都有一个字符串类型的事件类型(type)和一个回调函数(handler),回调函数的第一个参数是 state。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

调用

store.commit('increment');

pinia没有mutations属性

Actions

vuex
actions 用于提交 mutations,但不同的是,actions 支持异步操作。在 actions 中执行异步操作(如 API 请求)后,再通过 commit 来触发 mutation 以修改状态。

const store = new Vuex.Store({
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  }
})

在组件使用

<template>
  <button @click="incrementAsync">Async Increment</button>
</template>

<script>
export default {
  methods: {
    incrementAsync() {
      this.$store.dispatch('incrementAsync');
    }
  }
};
</script>

当然,如果actions多的话,你也可以选择使用映射

import { mapActions } from 'vuex';
  methods: {
    ...mapMutations(['increment']),
    ...mapActions(['asyncIncrement'])
  }

pinia

// store.js
import { defineStore } from 'pinia';

export const useStore = defineStore('main', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++;
    },})

在组件中使用

<template>
  <div>
    <button @click="counterStore.increment">Increment</button>
  </div>
</template>

<script setup>
import { useCounterStore } from '@/stores/counter';
const counterStore = useCounterStore();
</script>


工作原理

vuex:
Vuex 基于以下机制来实现其核心功能:
响应式的 state:Vuex 利用 Vue.js 自身的响应式系统来确保 state 的变化会自动引发界面的更新。
单一状态树:Vuex 通过单一的状态树将所有的状态集中管理,每个组件都可以通过这个状态树访问和修改数据,避免了多层嵌套传递数据的问题。
不可变的 state:只有通过提交 mutation 才能修改 state,这种方式确保了状态的可追踪性。通过 Vue 开发工具,开发者可以轻松地查看每一次 mutation 是如何改变状态的。
在这里插入图片描述
pinia

  1. 创建 Pinia 实例:
    createPinia() 用于生成 Pinia 实例,这个实例你可以将其看作为一个全局的 store 容器,用来保存所有的 Vuex store。

  2. 创建 Store:
    使用 createStore 可以创建一个新的 store,这个 store 可看做是一个独立的状态管理空间,其中包含了 state、getters 和 actions,被创建的 store 实例会被自动添加到 Pinia 实例中。

  3. 使用 Store:
    我们通过在组件中调用用 createStore 创建的 store 函数,来获取对应的 Pinia store 的实例。然后,我们就可以访问其中的 state、getters,或者执行 actions 里定义的方法。

  4. 监听 Store 变化:
    我们可以使用 Vue 的 watchwatchEffect 函数来监听 store 中 state 或 getters 的变化,以便在这些内容改变时执行相应的操作。

  5. 整合到 Vue App 中:
    创建的 Pinia 实例需要使用 app.use() 安装到 Vue App 中,以便 Pinia 与 Vue App 一同工作,提供全局的状态管理能力。

优缺点

Vuex 的优点

  1. 成熟稳定:Vuex 已经存在很长时间,社区和文档非常完善。
  2. 模块化支持:Vuex 提供了强大的模块化支持,可以将状态拆分成多个模块进行管理。
  3. 严格的约束:Vuex 的严格约束有助于保持代码的一致性和可维护性。

Vuex 的缺点

  1. 语法复杂:Vuex 的语法相对较为复杂,初学者可能需要一些时间来适应。

  2. 冗长的代码:由于 Vuex 的严格约束,代码可能会变得冗长和重复。

Pinia 的优点

  1. 简洁的 API:相比 Vuex,Pinia 不再需要 mutations,状态的修改可以直接通过 actions 或者直接修改 state,减少了模板代码,使状态管理更直观。
  2. 支持组合式 API:Pinia 完美集成了 Vue 3 的组合式 API(Composition API),和 setup
    直接结合使用,减少了复杂性。
  3. TypeScript 支持:Pinia 原生支持 TypeScript,提供类型推断和自动完成,让开发者在使用 Pinia
    时更加方便,减少了手动添加类型的麻烦。
  4. 模块自动化:不需要像 Vuex 那样手动注册模块,Pinia 的 store 是独立的,自动按需加载,无需管理模块的注册和取消注册。
  5. 开发工具支持:Pinia 支持 Vue Devtools,并提供了时间旅行和状态快照功能,方便调试。

Pinia 的缺点

  1. 社区支持较少:虽然 Pinia 是官方推荐的 Vue 3 状态管理工具,但它相对于 Vuex
    来说是较新的库,社区资源和插件的生态系统还没有 Vuex 丰富。
  2. 学习成本:对于已经熟悉 Vuex 的开发者,迁移到 Pinia
    需要一些学习时间,尤其是在大型项目中迁移状态管理可能会涉及较大的代码修改。
  3. 不支持 Vue 2:Pinia 是专门为 Vue 3 设计的,无法与 Vue 2 一起使用。如果需要在 Vue 2中使用状态管理,仍然需要使用 Vuex。
  4. 性能:虽然 Pinia 的性能相较 Vuex 有所提升,但在非常大规模的项目中,状态管理的性能瓶颈问题可能仍然存在。此时需要配合 Vue
    的响应式原理和一些手动优化来保证性能。

http://www.kler.cn/a/379410.html

相关文章:

  • 九,数据类型存储
  • vue3中使用vue-diff工具来比较数据差异
  • 彻底理解链表(LinkedList)结构
  • 【Clikhouse 探秘】ClickHouse 物化视图:加速大数据分析的新利器
  • 解决Java接口接受附件入参失败的问题
  • Netty学习——NIO基础与IO模型
  • 什么是虚拟dom,如何实现一个虚拟dom
  • 硅谷甄选(10)用户管理
  • HTML5 + CSS3 + JavaScript 编程语言学习教程
  • Rust编程中的浮点数比较
  • Spring Boot 3.x 整合 Druid 数据库连接池(含密码加密)
  • Docker安装MySQL8.0
  • LeetCode 热题100 之 回溯1
  • 已解决:VS2022一直显示编译中但无法运行的情况
  • 贝叶斯+PINN!双重热点buff叠加,轻松斩获Nature子刊!
  • 人工智能技术的演变与未来:前景、挑战与应对
  • Lobe Chat:你的私人AI助理
  • Kimi出考题,考题提示词Prompt附上,培训机构试题、期中考试、人事入职试题全搞定
  • Three.js基础入门笔记
  • Centos安装ZooKeeper教程(单机版)
  • DBA之路,始于足下
  • I2S、PDM、PCM、TDM、DSM、DCODEC、VAD、SPDIF
  • 损失函数1
  • 「实战应用」如何在 DHTMLX Scheduler 中实现动态主题切换?
  • SpringBoot day 1104
  • ValueError: set_wakeup_fd only works in main thread