深入浅出 Pinia:革新 Vue 状态管理的利器 ⚡

什么是pinia?

官方解释:Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

说白了就相当于一个数据储存库,开发者可以将其内部储存的数据应用到各个组件上。pinia对于部分小型项目来说有时候是多此一举,但是对于中大型项目来说是不可或缺的,利用pinia可以很好的解决组件之间状态共享和管理等一系列麻烦。(其前身是Vuex,这里就不过多赘述了)

使用 pinia 的好处

优胜劣汰是自然法则,其同样适用于项目,每个库或工具都有其存在的价值,而pinia也是有一定优点才会被开发者使用。

  • 直观易用的API:pinia提供了state(状态)、getter(计算属性)、action(业务逻辑),抛弃了Vuex中的Mutation。
  • 模块化设计:可以创建多个 store,并且将其分割成不同的模块,有利于大型项目的组织和维护。
  • 轻量级:Pinia 库本身非常轻量,对应用性能影响极小。
  • 良好的 TypeScript 支持:对 TypeScript 的支持非常好,提供了完全类型化的 API。
  • 兼容性好:对于 Vue 3 和 Vue 2 都支持。
  • 插件系统:Pinia 允许开发者扩展其功能。

当然其优点远远不止这些,读者可以在开发时自行体会。

pinia 的基本使用

一、安装 pinia

bash 复制代码
npm install pinia 
# 或者
yarn add pinia

将pinia挂载到Vue上,并且创建一个pinia实例(store 根储存):

js 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './style.css'
import App from './App.vue'

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

二、创建 store

这里创建 store 其实是创建一个用于集中管理和保存应用全局状态的仓库,并且我们需要 pinia 提供的defineStore()方法来创建一个 store ,其用来存放我们需要全局使用的数据。

具体一般是在 src 文件夹中创建一个 store 文件夹用于存放我们创建的 store,在其目录下就可以新建各种需要的 store 了。例如:创建一个存放user数据的store。

js 复制代码
// src/store/user.js

import { defineStore } from 'pinia'

// 第一个参数是应用程序中 store 的唯一 id
export const useUserStore = defineStore('user', () => {
    // 其他配置...
})

defineStore的第二个参数可以接收两种值:Setup 函数或 Option 对象。

setup 函数

其与 Vue 组合式 API 的 setup 函数 很相似,传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。例如:

js 复制代码
export const useUserStore = defineStore('user', () => {
  const count = ref(0);
  const doubleCount = computed(() => count.value * 2);
  
  function increment() {
    count.value++;
  }

  return { 
      count,
      doubleCount,
      increment,
  }
})
Option 对象

其与 Vue 的选项式 API 类似,传入一个带有 stateactionsgetters 属性的对象。例如:

js 复制代码
export const useUserStore = defineStore('user', {
  // 可以将 state 看作是组件的data选项,返还一个带有你的状态的对象
  state: () => ({ 
      count: 0, 
      name: 'xixili', 
  }),
  
  // getter 是 state 的计算属性,可以衍生出一些状态,并且其接收 state 作为参数
  getters: {
    doubleCount: (state) => state.count * 2
  },
  
  // actions 用来执行状态更改的函数,可以是同步的,也可以是异步的
  actions: {
    increment() {
      this.count++;
    },
  },
})

这两种用法各有各的优势和劣势,挑选自己喜欢的使用即可。


三、使用 store

定义完 store ,接下来就是在需要的组件内调用即可。

html 复制代码
<script setup>
import { useUserStore } from '../store/user.js'
// 这样可以在组件中的任意位置访问 `store` 变量
const userStore = useUserStore();
</script>

实战实例:

安装完并挂载后就可以开始操作了,在 store 文件夹内部创建counter.js

js 复制代码
// counter.js

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

// 仓库名 函数
export const useCounterStore = defineStore('counter', () => {
    const count = ref(0);

    function increment() {
        count.value++; 
    }
    return {
        count,
        increment,
    }
})

为了体现一个 store 可以在多个组件内同时使用,分别创建CompA.vueCompSubA.vue.

html 复制代码
<!-- CompSubA.vue -->
<template>
    <div>
        CompSubA
        {{ count }}
        <hr>
        {{ counterStore.count }}
    </div>
</template>

<script setup>
import { toRefs } from 'vue';
import { useCounterStore } from '../store/counter';
const counterStore = useCounterStore(); // 本地和中央连接的过程
const { count } = toRefs(counterStore);
// const { count } = counterStore(); 解构
</script>

<style  scoped>

</style>

注: 注释中的解构是没有问题的,但是这样就丢失了响应式,如果还要保持响应式,就需要toRefs方法。

html 复制代码
<!-- CompA.vue -->

<template>
    <div>
        <h2>CompA</h2>
        <p>count: {{ counterStore.count }}</p>
        <button @click="counterStore.increment">Add</button>
        <CompSubA />
    </div>
</template>

<script setup>
import CompSubA from './CompSubA.vue';
// 引入中央模块
import { useCounterStore } from '../store/counter';
const counterStore = useCounterStore();
</script>

<style scoped>

</style>

最后呈现的效果为:

并且其支持开发者工具Vue Devtools,并且可以手动修改调试数据。

相关推荐
写代码的小王吧1 小时前
【安全】Web渗透测试(全流程)_渗透测试学习流程图
linux·前端·网络·学习·安全·网络安全·ssh
小小小小宇2 小时前
CSS 渐变色
前端
snow@li2 小时前
前端:开源软件镜像站 / 清华大学开源软件镜像站 / 阿里云 / 网易 / 搜狐
前端·开源软件镜像站
小小小小宇3 小时前
配置 Gemini Code Assist 插件
前端
one 大白(●—●)3 小时前
前端用用jsonp的方式解决跨域问题
前端·jsonp跨域
刺客-Andy3 小时前
前端加密方式 AES对称加密 RSA非对称加密 以及 MD5哈希算法详解
前端·javascript·算法·哈希算法
前端开发张小七3 小时前
13.Python Socket服务端开发指南
前端·python
前端开发张小七3 小时前
14.Python Socket客户端开发指南
前端·python
ElasticPDF-新国产PDF编辑器4 小时前
Vue 项目 PDF 批注插件库在线版 API 示例教程
前端·vue.js·pdf
拉不动的猪4 小时前
react基础2
前端·javascript·面试