【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)
}
相关推荐
拆房老料21 分钟前
ONLYOFFICE也能像Microsoft Word和WPS一样分别设置中西文字体
前端·html·word·开源软件·wps
VX_bysjlw98535 分钟前
数码设备销售网站设计与实现39138-计算机毕设原创(免费领源码+带部署教程)
java·vue.js·spring boot·mysql·tomcat·mybatis·idea
Solis程序员37 分钟前
Stripe 幂等表:把「不确定的重试」变成「查表返回」
前端·安全·bootstrap·php·agent
李纲明1 小时前
WordPress 站点变慢:按 TTFB → 缓存 → 查询 → 前端 分层排查(含配置注意)
前端·缓存·性能优化·wordpress·后端开发
程序人生8881 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
粥里有勺糖2 小时前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
xy34532 小时前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计
不停喝水2 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
一水鉴天3 小时前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css
栖凤3 小时前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python