【Vue3进阶】- Pinia 用法

什么是Pinia

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。它提供了类似于 Vuex 的功能,但比 Vuex 更加简单和直观

需要在多个组件之间共享状态或数据时使用 Pinia 的 store,这样可以避免 props 和 eventBus 等传统方法的复杂性,使状态管理更加集中和可维护。

安装

  1. 在终端中输入 npm install pinia
  2. 在main.js中引入 pinia,并且通过 app.use() 安装;
javascript 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'   // 引入
import App from './App.vue'

const pinia = createPinia() 	      // 创建实例
const app = createApp(App)

app.use(pinia)			      // 安装使用
app.mount('#app')

定义Store

一般会在 store 目录下创建相应模块名字的js文件中定义; 例如:定义 user 模块要用到的 store,首先创建 /src/store/demo.js 文件。

接着使用 defineStore 方法定义 store:

  1. defineStore 定义的返回值(示例中的 useDemoStore)可以自己任意命名,但是建议以 use + store名字 + Store 的形式来定义(例如:useUser Store、useCartStore...)。

  2. defineStore 的第一个参数是应用中 Store 的唯一 ID(示例中的"demo")。

  3. defineStore 的第二个参数可接受两类值:Setup 函数Option 对象,后面内容将只介绍 Option 对象。

javascript 复制代码
// /src/store/demo.js

import { defineStore } from 'pinia'

export const useDemoStore = defineStore('demo', {
    // 其他配置...
})

Option

State

state 是一个返回初始状态的函数

javascript 复制代码
// /src/store/demo.js

import { defineStore } from 'pinia'

export const useDemoStore = defineStore('demo', {
  state: () => {
    return { // 在返回对象中定义要使用的数据
      count: 0,
      name: 'd2school',
      isAdmin: true,
      arr: [1,2,3]
    }
  },
})

访问state

使用定义的 store 实例就可以直接对其 state 进行读写 。 例如:上面定义的 store 返回值是 useDemoStore ,那么使用方式为:

javascript 复制代码
import {useDemoStore} from "/src/store/demo.js";

const demoStore = useDemoStore()  // store实例

store.name     // 'd2school' 访问到state的内容
store.count++  // 1  进行修改

变更state

除了 store.count++ 直接对 state 进行修改,也可以使用 $patch 同时更改多个属性。

javascript 复制代码
demoStore.$patch({
  count: demoStore.count + 1,
  name: 'd2school.com',
  isAdmin: false,
})

使用这种语法时,某些变更会比较麻烦或者耗时。 例如:对数组的增删操作,都需要创建一个新的集合,因此 $patch 方法也接受一个函数来进行变更。

javascript 复制代码
demoStore.$patch((state) => {
  state.arr.push(3)
  state.isAdmin= false
})

重置state

使用 store 实例的 $reset() 方法可以将 state 重置为初始值。

javascript 复制代码
import {useDemoStore} from "/src/store/demo.js";

const demoStore = useStore() // store实例

demoStore.$reset()   // 重置

Getter

getter 是 state 的计算值,建议使用箭头函数,它将接收 state 作为第一个参数。

在 getter 中可以使用 this 访问到整个 store 实例。

javascript 复制代码
// /src/store/count.js
export const useCountStore = defineStore('count', {
  state: () => ({
    count: 1,
  }),
  getters: {
    // 返回2倍数的count
    doubleCount(state) {
      return state.count * 2
    },
    // 返回两倍的count并且+1
    doublePlusOne(){
      return this.doubleCount + 1  // 可以使用this访问到整个store实例
    },  
},
})

直接在 store 实例上访问 getter。

vue 复制代码
<script setup>

import { useCounterStore } from '/src/store/counterStore.js'
const countStore = useCountStore ()

countStore.doubleCount    //  2
countStore.doublePlusOne  //  3

</script>

<template>
  <p>{{ store.count}}</p>
  <p>{{ store.doubleCount }}</p>
</template>

Action

action 相当于组件的 methods,可以执行异步操作,处理业务逻辑。

javascript 复制代码
import {defineStore} from 'pinia'

export const useDemoStore = defineStore('demo', {
    // 其他配置...
    state: () => {
        return {
            count: 0
        }
    },
    actions: {
        modifyCount(val) {
            this.count = val < 5 ? val : 0 // val小于5则赋值val否则赋值0
        }
    }
})

同样可以直接在 store 实例上访问 actions。

javascript 复制代码
import {useDemoStore} from "./store/demo.js";
import {ref} from "vue";

const store = useDemoStore()
let count = ref(0)

function change() {
  count.value++
  store.modifyCount(count.value)
}
相关推荐
专业抄代码选手几秒前
03|React 为什么需要协调:比较两棵树,而不是重建页面
前端·javascript·react.js
灯澜忆梦3 分钟前
【基于GO的Web开发11】gin获取URL‑Path 路径参数
前端·后端·golang·html·gin
王霸天3 分钟前
GLB 文件太大怎么办?我把它从 47MB 压到 8MB,全程没碰命令行
前端·javascript·程序员
半个落月3 分钟前
Next.js 16 笔记应用实战:Redis 数据链路与组件两版拆分详解
前端·redis·next.js
YIAN4 分钟前
告别等后端!React+Vite 前端独立开发全流程:接口封装 + Mock 方案 + 状态管理
前端·react.js·vite
PedroQue998 分钟前
@meng-xi/vite-plugin v1.3.0:generateUni 一键流水线
前端·vite
胡萝卜术9 分钟前
权限系统的四道防线:从数据库事务锁到操作级保护规则的完整设计
前端·javascript·面试
IMPYLH9 分钟前
HTML 的 <legend> 元素
java·前端·html
真夜12 分钟前
RN热更新安全问题
前端·react native
Zeroplucky13 分钟前
Binder 线程池耗尽案例:持锁同步调用 VHAL 导致 SystemUI 卡顿或 ANR
前端