Vue里面的状态管理库Pinia

207 阅读6分钟

引言

在了解状态管理库Pinia之前,我们先回顾一下组件通信,我们有父传子子传父,那么我们想要子--子之间进行通信,那怎么办呢?传统的,我们如果只知道父组件和子组件进行通信,就只能子组件1传给父组件,然后父组件再传给子组件2,想一想,这样会不会太麻烦了?我们可不可以定义一些公共数据,让任意组件都可以获取呢?

简单介绍一下Pinia

Pinia是一个用于Vue应用程序的状态管理库,它旨在提供一种更简洁、更现代的方式来处理跨组件状态共享,,主要用于在Vue应用中管理全局状态,即那些需要在多个组件之间共享和访问的数据。

关键词:跨组件之间进行通信

下面,让我们来了解一下Pinia的基本用法

  1. 安装Pinia: 使用npm或yarn安装Pinia包,指令:npm i pinia

  2. 创建store: 定义你的状态、actions和getters,并创建一个store模块。

  3. 激活Pinia: 在主应用文件中,通过createPinia()创建Pinia实例,并使用app.use()将其注入到Vue应用中。

  4. 使用store: 在组件中通过组合API的useStore函数来访问store,或者在选项API中使用provide/inject来访问store。

文件引入

main.js里面

  1. 引入 createPinia 函数(来自 pinia 包)。

  2. 创建 Pinia 实例

  3. 创建 Vue 应用实例: 使用 createApp 创建 Vue 应用实例,并传入根组件。

  4. 使用 Pinia: 在创建的 Vue 应用实例上使用 Pinia。这会将 Pinia 的状态管理功能注入到整个应用中。

  5. 挂载应用: 将 Vue 应用挂载到 DOM 中的某个元素上,通常是 #app

 import { createApp } from 'vue';      引入 `createPinia` 函数(来自 `pinia` 包)。
 import { createPinia } from 'pinia';  
 import App from './App.vue';
 const pinia = createPinia();            // 创建 Pinia 实例
 const app = createApp(App);              //创建 Vue 应用实例,并传入根组件
  app.use(pinia);                        // 使用 Pinia
  app.mount('#app');                      //挂载应用

这里,main.js里面的内容我们就完成了

接下来,一般情况下,我们在src文件夹下面创建一个名叫stores的文件夹,stores的文件夹下面创建一个counter.js文件

counter.js里面

  1. 引入 Pinia: 首先,你需要从 pinia 包中引入 defineStore 函数,用于定义 store。
   import { defineStore } from 'pinia'
  1. 定义 Store: 使用 defineStore 函数来创建一个 store。你可以定义多个 store,每个 store 通常负责管理应用中特定部分的状态。
    const useCounterStore = defineStore()

Pinia存储数据



import { ref,computed } from 'vue' 
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => 
{ 
const count = ref(0) const name =ref('宇哥')
const doubleCount = computed(() => count.value * 2) 
function increment() { count.value++ 
}

return { count, doubleCount,name, increment } })

解释

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

  • refcomputed 是 Vue 3 Composition API 中的两个核心函数,用于创建响应式数据和计算属性。
  • defineStore 是 Pinia 提供的函数,用于定义一个状态管理器。
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const name = ref('宇哥')
  const doubleCount = computed(() => count.value * 2)
  
  function increment() {
    count.value++
  }
  
  return { count, doubleCount, name, increment }
})

  • defineStore('counter', () => { ... }) 定义了一个名为 counter 的状态管理器。
  • count 是一个通过 ref 创建的响应式变量,初始值为 0
  • name 也是通过 ref 创建的响应式变量,初始值为 '宇哥'
  • doubleCount 是一个通过 computed 创建的计算属性,它的值是 count.value 的两倍。
  • increment 是一个函数,用于增加 count 的值。
  • return { count, doubleCount, name, increment }countdoubleCountnameincrement 这些变量和函数暴露给外部使用。

接下来,我们来访问一下我们仓库里定义的数据

<template>
  <div>
     数量: {{ count }}
     <br>
     姓名:{{ name }}
  </div>
</template>
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";
const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)

</script>

<style lang="scss" scoped>
</style>

解释一下代码


<template>
  <div>
    数量: {{ count }}
    <br>
    姓名:{{ name }}
  </div>
</template>

  • 这部分定义了组件的模板。在模板中,通过 {{ count }}{{ name }} 来显示从状态管理器中获取的 countname 的值。
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";

const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)
</script>

  • import { useCounterStore } from "@/stores/counter.js" 导入了之前定义的 useCounterStore,该函数返回了一个 Pinia 的 store 实例。
  • import { storeToRefs } from "pinia"; 导入了 storeToRefs 函数,用于将 store 实例中的响应式数据转换为普通的 ref 对象。
  • const useStore = useCounterStore() 调用 useCounterStore 函数得到一个实例 useStore
  • const { count, name } = storeToRefs(useStore) 使用 storeToRefsuseStore 中的 countname 转换为普通的响应式对象。

常出现的错误!!!!!

如果是export xxxxxxxx

引入的话,就需要 import {xxxxxx} from ''

如果是 expotr default xxxxxxxx

引入的话,就 import xxxxxx from ''

这是我学Vue的时候经常出现的我问题,给大家分享一下

  • 命名导出 (export { ... }): 允许一个模块导出多个变量、函数或对象,并且每个导出都有一个明确的名字。这种方式使得在导入时可以选择性地导入需要的部分,不需要导入整个模块的内容。
  • 默认导出 (export default ...): 通常用于导出一个模块中的主要功能或对象,使得在导入时可以更简洁地引用,默认导出的内容可以使用任何合法的标识符来命名,而不需要花括号 {} 包裹。

怎么通过Pinia修改数据呢

如果我们想把 宇哥改为鹿哥,并且每点一次加一,count就加一,该怎么办呢?

在这里,我们在Pinia里面定义一个改名名字的函数,抛出,然后,让组件去调用

App.vue


 <template>
  <div>
    数量: {{ count }}
    <br>
    姓名:{{ name }}
    <br>
    <button @click="change()">点击修改姓名,变为鹿哥</button>
    <br>
    <button @click="add()">点击加一</button>
  </div>
</template>
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";
const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)
function change(){
    
    useStore.changeName('鹿哥')
}
function add(){
  useStore.Add()
}
</script>
<style lang="scss" scoped>
</style>

counter.js

import { ref,computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const name =ref('宇哥')
  const doubleCount = computed(() => count.value * 2)
  function Add() {
    count.value++
  }
  function changeName(name)
  {
     this.name=name
  }

  return { count, doubleCount, name, Add, changeName }
})

counter.js里面,我们定义了一个changeName(改变姓名)和一个Add,(点击数量加一)的两个函数,这两个函数在App.vue里面进行调用

最终的结果是:点击姓名变为鹿哥, 点击加以 数量加一

微信截图_20240708214829.png

总结

在本文中,我们首先探讨了传统的Vue组件通信方式以及其局限性,随后介绍了Pinia作为现代化的Vue状态管理库的基本概念和使用方法。Pinia的安装和配置过程包括创建和定义store,以及在主应用中激活和使用Pinia实例。我们详细讨论了如何在组件中访问和修改Pinia store中的数据,例如通过计算属性和响应式数据管理计数器和姓名,并通过实例方法实现对数据的修改。

制作不易,感谢支持