Vue替代vuex的存储库Pinia详细介绍

 更新时间:2022年09月16日 09:34:03   作者:super_wanan  
这篇文章主要介绍了Vue替代vuex的存储库Pinia,听说pinia与vue3更配,便开启了vue3的学习之路,pinia 和 vuex 具有相同的功效, 是 Vue 的存储库,它允许您跨组件/页面共享状态

前言

vue3已经发布很长一段时间了,vue官网也已经默认访问vue3的文档了。因此打算系系统统仔仔细细的学习一波

使用官方提供的脚手架工具新建一个vue3项目会发现,官方已将pinia作为默认的状态存储库提供在安装选项中了。

vuex的仓库中官方也有这么一段提示:

大致是说:Pinia 现在是新的默认设置。Vue 的官方状态管理库已更改为Pinia。您可以简单地将 Pinia 视为具有不同名称的 Vuex 5。Pinia 也适用于 Vue 2.x。Vuex 3 和 4 仍将被维护。但是,不太可能为其添加新功能。如果您打算开始一个新项目,我们强烈建议您使用 Pinia。

本文就来介绍打败vuex的新一代vue存储库Pinia究竟有和神奇魔法~

Pinia介绍

u1s1,logo真可爱~

Pinia(发音为 /piːnjʌ/,类似于英语中的“peenya”)是最接近有效包名 piña(西班牙语中的_pineapple_)的词。 菠萝实际上是一组单独的花朵,它们结合在一起形成多个水果。 与 Store 类似,每一家都是独立诞生的,但最终都是相互联系的。 它也是一种美味的热带水果,原产于南美洲。

1. 创建一个Pinia store

安装pinia

npm install pinia

注意虽然pinia支持vue2.x和vue3.x,但是如果你的vue的版本低于2.7,还需要安装组合API:@vue/composition-api。

2. 创建一个根存储并传递给应用程序

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')

如果你使用的是vue2,还需要安装一个插件并将创建的pinia注入应用程序的根目录

import { createPinia, PiniaVuePlugin } from 'pinia'
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
new Vue({
  el: '#app',
  // 其他选项...
  // ...
  // 注意同一个 `pinia` 实例可以在多个 Vue 应用程序中使用
  // 同一个页面
  pinia,
})

3. 定义一个store

export const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      count: 0,
      msg: '开心',
      todoList: ['吃饭', '绘画']
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  },
  actions: {
    increment(payload?: number) {
      this.count = payload ? this.count + payload : this.count + 1
    }
  }
})

2. 访问State

  <template>
	<div class="about">
		<p>{{ counterStore.msg }}</p>
	    <p>{{ counterStore.count }}</p>
	    <p>{{ counterStore.doubleCount }}</p>
	    <p @click="() =>counterStore.increment(3)">点击我+1</p>
  </div>
  </template>
  <script setup lang="ts">
	  import { storeToRefs } from 'pinia'
	  import { useCounterStore } from '@/stores/counter'
	  const counterStore = useCounterStore()
  </script>

你也可以使用storeToRefs进行解构

<template>
  <div class="about">
    <p>{{ count }}</p>
    <p>{{ msg }}</p>
    <p>{{ doubleCount }}</p>
    <ul>
      <li v-for="(item, index) in todoList" :key="index">{{ item }}</li>
    </ul>
  </div>
</template>
<script setup lang="ts">
  import { storeToRefs } from 'pinia'
  import { useCounterStore } from '@/stores/counter'
  const counterStore = useCounterStore()
  // 也可以使用storeToRefs进行解构
  let { count, doubleCount, msg, todoList } = storeToRefs(counterStore)
</script>

3. Pinia修改数据的四种方法

直接修改

counterStore.count++

$patch

$patch 方法允许你使用部分“state”对象同时应用多个更改。 但是,使用这种语法应用某些突变非常困难或代价高昂:任何集合修改(例如,从数组中推送、删除、拼接元素)都需要创建一个新集合。

const newTodoList = [...counterStore.todoList, '睡午觉']
counterStore.$patch({
	 count: 100,
	 msg: '哈哈',
	 todoList: newTodoList
})

$patch传递函数

$patch 方法也接受一个函数来批量修改集合内部分对象的情况

counterStore.$patch((state) => {
    state.count = 100,
    state.msg = '哈哈',
    state.todoList.push('听音乐')
})

action

当业务逻辑很复杂的时候,可以将方法写在store中的action里

actions: {
    increment(payload?: number) {
      this.count = payload ? this.count + payload : this.count + 1
    }
}

4. 重置State

可以通过调用 store 上的 $reset() 方法将状态 重置 到其初始值

counterStore.$reset()

5. 替换state

通过将其 $state 属性设置为新对象来替换 Store 的整个状态

counterStore.$state = {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> counter: 666, msg: 'Paimon', todoList: [] }

也可以通过更改 pinia 实例的 state 来替换应用程序的整个状态。 这在 SSR for hydration 期间使用。

pinia.state.value = {}

6. 订阅状态

可以通过 store 的 $subscribe() 方法查看状态及其变化,类似于 Vuex 的 subscribe 方法。 与常规的 watch() 相比,使用 $subscribe() 的优点是 subscriptions 只会在 patches 之后触发一次。

counterStore.$subscribe((mutation, state) => {
  // 每当它发生变化时,将整个状态持久化到本地存储
  localStorage.setItem('cart', JSON.stringify(state))
})

7. Getters

Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用。

export const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      count: 0,
      msg: '开心',
      todoList: ['吃饭', '绘画']
    }
  },
  getters: {
  //自动将返回类型推断为数字
    doubleCount(state) {
      return state.count * 2
    }
  }
})

在getters中使用其他 getter:

getters: {
	// 返回类型必须明确设置
    doublePlusOne():number {
      return this.doubleCount + 1
    }
  }

将参数传递给 getter:

getters: {
    getUserById: (state) => {
      return (userId) => state.users.find((user) => user.id === userId)
    },
  }

在组件中这样使用:

<template>
  <p>User 2: {{ counterStore.getUserById(2) }}</p>
</template>

与vuex比较

Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法。最终,团队意识到 Pinia 已经实现了他们在 Vuex 5 中想要的大部分内容,并决定实现它。与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。

  1. mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
  2. 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
  3. 不再需要注入、导入函数、调用函数、享受自动完成功能
  4. 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心
  5. 不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
  6. 没有命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。

Pinia的优点

  1. 同时支持vue2与vue3
  2. 摒弃了mutations,只有state,getter,action
  3. Actions支持同步和异步
  4. 更符合Vue3的Composition api
  5. 天然支持ts

到此这篇关于Vue替代vuex的存储库Pinia详细介绍的文章就介绍到这了,更多相关Vue Pinia内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue-cli2打包前和打包后的css前缀不一致的问题解决

    vue-cli2打包前和打包后的css前缀不一致的问题解决

    这篇文章主要介绍了vue-cli2打包前和打包后的css前缀不一致的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 详细讲解vue2+vuex+axios

    详细讲解vue2+vuex+axios

    在vue2项目中,组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的情况下(后台获取数据存入vuex,组件之间共享数据),那么就需要用vuex来管理这些。
    2017-05-05
  • 使用Vue父子组件通信实现todolist的功能示例代码

    使用Vue父子组件通信实现todolist的功能示例代码

    这篇文章主要给大家介绍了关于如何使用Vue父子组件通信实现todolist的功能的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • vue整合百度地图显示指定地点信息

    vue整合百度地图显示指定地点信息

    本文主要介绍了vue整合百度地图显示指定地点信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • go-gin-vue3-elementPlus带参手动上传文件的案例代码

    go-gin-vue3-elementPlus带参手动上传文件的案例代码

    这篇文章主要介绍了go-gin-vue3-elementPlus带参手动上传文件的案例代码,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-11-11
  • vue实现引入本地json的方法分析

    vue实现引入本地json的方法分析

    这篇文章主要介绍了vue实现引入本地json的方法,结合实例形式分析了vue.js加载本地json文件及解析json数据相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • Vue3中Pinia的基本使用笔记

    Vue3中Pinia的基本使用笔记

    Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐,下面这篇文章主要给大家介绍了关于Vue3中Pinia的基本使用,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • vue3封装简易的vue-echarts问题

    vue3封装简易的vue-echarts问题

    这篇文章主要介绍了vue3封装简易的vue-echarts问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • vue-cli 使用vue-bus来全局控制的实例讲解

    vue-cli 使用vue-bus来全局控制的实例讲解

    今天小编就为大家分享一篇 vue-cli使用vue-bus来全局控制的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue中如何判断对象是否为空

    Vue中如何判断对象是否为空

    这篇文章主要介绍了Vue中如何判断对象是否为空,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论