【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)
}
相关推荐
mldong32 分钟前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排1 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60612 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角3 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰3 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi5 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen5 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马6 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒6 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端