Vue的热心大菠萝——Pinia

806 阅读8分钟

前言

Vue 作为一个流行的前端框架,早期的状态管理解决方案主要依赖于 Vuex。然而,随着 Vue 3 的发布,一个新的状态管理库 Pinia 诞生了。Pinia 致力于提供更简单、更高效、更易用的状态管理体验,下面将带大家来了解一下这个大菠萝。

PixPin_2024-12-29_21-31-23.gif

1. 什么是Pinia

Pinia 是一个轻量级的状态管理库,专门为 Vue 3 应用程序设计。它是 Vuex 的现代替代品,旨在提供更简单、更高效、更易用的状态管理体验。

这段话说起来可能有点太官方了,我们用大白话来说呢就是可以为我们提供一个公用的大仓库,可以方便组件之间的通信。

在vue中如果想要实现组件之间的通信的话,比如父子通信通常会使用props来实现这个功能,由于vue是组件式开发,那么如果嵌套了很多层vue的话想要从祖宗传到后辈中去的话虽然说可以一直props无限套娃来实现,但是未免过于麻烦,这时候如果有一个公共区域可以方便我们来存取需要的资源的话,那就不用这么麻烦了,而Pinia就能实现这个功能,效果类似于下面这张图:

image.png

2. Pinia的用法

2.1 安装Pinia

在Vue中如果我们想使用额外的包的话首先我们得先在vue项目中安装一个Pinia,我们可以在vue项目的控制台中输入下面两个中的一个指令:

yarn add pinia
npm install pinia

安装完成后,就需要在vue中导入Pinia,相信之前学习过router路由的同学并不陌生,我们需要在main.js文件中导入Pinia,并且use掉它:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
import store from './store'

// use都在mount之前,顺序无所谓
createApp(App).use(router).use(store).mount('#app')

我们在main.js中引入了store之后,就该为Pinia配置一下了其实应该先配置一下的,这个过程呢如果记不住的同学可以参考一下路由的配置,我们在配置路由的时候,在src中创建了router文件夹并在下面放置了index.js,同理我们在src中创建store文件夹并且在其中创建index.js文件用来配置仓库,在index.js中我们输入以下代码:

import { createPinia } from "pinia"; 

const store = createPinia()//为了让vue和pinia源码融合使用

export default store

2.2 Pinia的使用 —— Store

经过了上面的步骤之后,我们就拥有自己的一个大菠萝仓库了,下面我们用一个小小的案例来教大家如何使用Pinia,先给大家看一下完成这个页面之后的小效果:

PixPin_2024-12-30_11-31-17.gif

首先先给大家看一下案例的文件构成:

image.png

简单给大家说一下,当我们运行项目时,将页面重定向到了Home.vue这个组件中,并且在这个组件中我们导入了Car.vueList.vue两个组件用以展示案例样式。我们想要让Car.vue和List.vue两个组件共同使用一些变量的话用父子通信就有点麻烦,而如果能有一个仓库可以直接让他们取数据,那么就能非常便捷,下面我们来看看如何使用Store来实现这个功能。

定义Store

我们如果想使用Pinia首先要定义一个仓库,在Store文件夹中创建一个Car.js用来存放我们需要公共使用的数据,在js文件中我们首先需要引入一个pinia中的函数defineStore用来创建一个仓库:

import { defineStore } from "pinia"; // 开创一个可用的仓库

export const useCarStore = defineStore('car', () => {})

defineStore()有几点需要注意一下:

  1. defineStore 中的第一个参数是个字符串用来给仓库命名,这个命名是唯一的
  2. defineStore 中的第二个参数回调函数存放的数据是我们想要在仓库中存放的公共资源,如果想被读取到则需要返回一个对象,其中包含了想要抛出的变量或函数
  3. 在定义完了仓库之后需要我们对这个仓库进行抛出才能使用

在vue2中defineStore 中的第二个参数是个对象,具体可以参照官方

获取Store中的数据

咱得与时俱进,所以呢我们接下来就使用新版本的Pinia用法。在前文中我们说到如果想实现父子通信则需要通过props或者emit来进行传值,现在我们有了Store的话如果想取用一个公用的资源的话,我们只需要在仓库中按照js中定义变量或者函数的方式对想让其实现公用的变量或者函数进行定义即可。在定义完了之后如果想要被外界使用,那么就需要对其进行抛出。

在Store中我们首先定义了一个商品列表listArr用来展示商品,并且用一个数组来储存商品图片的信息:

image.png

我们如果想让仓库中的数据被外界所使用的话那么我们就需要将我们创建的仓库进行抛出,想要将仓库中的值取出的话则需要将需要取出的变量名或者函数名放在defineStore的回调函数中return出来的对象中。

像现在我们已经可以从仓库中拿到数据了,下面就该进行渲染了,那么我们如何在组件中获取仓库中的数据呢,下面直接给大家展示一下代码并进行讲解:

image.png

我们如果想要接收仓库中的数据首先要导入Store中抛出来的仓库并且它是个函数我们得进行调用:

import { useCarStore } from '../store/car';
const carStore = useCarStore()

由于调用useCarStore返回出来的是个对象,所以我们如果想调用从仓库中传出来的数据的话只需要按照使用对象中某个属性的方式即可,我们要将从仓库中拿到的商品信息渲染到页面上,用下面代码即可:

  <li v-for="(item, index) in carStore.listArr" :key="index">
  </li>

通过上面的例子我们可以得知,如果想使用仓库中的变量的话可以按照下面几个步骤:

  1. 先在仓库中按照js中的方式定义,然后在回调函数中以对象的形式抛出。
  2. 想要在外部使用的话先引入抛出的仓库,然后对其进行调用并且用变量接收
  3. 用使用对象某个属性的方式对接收仓库的变量或者函数进行使用即可

在这个使用仓库中资源的时候我们得注意一点:

如果想要修改仓库中的数据的话,最好使用仓库中所定义的函数在仓库中进行修改,以免造成数据污染

了解完了仓库的一些基本常识和使用方法之后,我们来实现一下将想要获取的商品点击添加按钮后可以让仓库中的selectArr来储存我们被选中的商品。

为了实现这个功能我们只需要在Store中定义一个方法addSelectArr,用来接收被选中商品的信息,并且将其pushselectArr中即可,下面我们来看一下仓库中的代码实现:

import { defineStore } from "pinia"; // 开创一个可用的仓库
import { computed, reactive } from "vue";

export const useCarStore = defineStore('car', () => {
  const listArr = [
    {
      pic: 'https://img0.baidu.com/it/u=3664559370,4167784460&fm=253&fmt=auto&app=138&f=JPEG?w=823&h=800',
      name: '无线蓝牙耳机',
      price: 100,
      desc: '高清音质 持久续航'
    },
    {
      pic: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcbu01.alicdn.com%2Fimg%2Fibank%2FO1CN01kT1RqH1xeqow7dlGT_%21%212208418306469-0-cib.jpg&refer=http%3A%2F%2Fcbu01.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1737114845&t=62fa6ec91546fa59b6f5eb71665fce06',
      name: '智能手表',
      price: 599,
      desc: '多功能运动监测'
    },
    {
      pic: 'https://img2.baidu.com/it/u=2406623817,3374856095&fm=253&fmt=auto&app=120&f=JPEG?w=750&h=500',
      name: '便携音响',
      price: 399,
      desc: '环绕立体声'
    },
    {
      pic: 'https://img2.baidu.com/it/u=402051968,367416785&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
      name: '移动电源',
      price: 199,
      desc: '大容量快充'
    }
  ]
  
  const selectArr = reactive([]) // 储存被选中的商品

  //想修改仓库的数据只能在仓库中修改,
  const addSelectArr = (item) => {
    selectArr.push(item)
  }
  return {
    listArr,
    selectNum,
    addSelectArr
  }
})

在仓库中对方法和变量定义之后我们只需要在需要使用它们的地方进行调用即可:

<template>
  <div class="list">
    <ul>
      <li v-for="(item, index) in carStore.listArr" :key="index">
        <img :src="item.pic"></img>
        <div class="name">{{ item.name }}</div>
        <p>{{ item.desc }}</p>
        <div class="price">
          <p>{{ item.price }}</p>
          <button @click="addCar(item)">加入购物车</button>
        </div>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { useCarStore } from '../store/car';

const carStore = useCarStore()

const addCar = (item) => {
  carStore.addSelectArr(item)  // 调用仓库的方法
}
</script>

3. 测试

最后效果就当成是给大家的一些小测试了,看看自己是否知道了Pinia的简单使用方法。 可以先跟大家讲解一下仓库中的一些变量以及大概思路:可以在仓库中定义一个变量用来检测购物车商品加入了多少,然后就是计算selectArr中的总价格了,最后直接把得出的价格以函数或者变量的形式返回即可。当然也可以在外部计算,只要不修改仓库中的数据即可

下面是仓库中的代码:

image.png

小结

总之,Pinia 以其简洁的 API、强大的功能和对 Vue 生态系统的深度融合,已经成为 Vue 开发者们新的首选。它不仅简化了状态管理的复杂度,还为开发者带来了更高效、更愉悦的开发体验。 以上呢就是Pinia的一些简单的使用方法,希望能帮助大家快速的了解一下Pinia是什么以及如何使用。

1732338928918.jpg