Pinia 上手使用(store、state、getters、actions)

本文介绍了Pinia,Vue.js的官方状态管理库,包括如何安装、在main.js中引入、创建store、获取和修改状态、使用getters,以及解构和辅助函数的使用方法。Pinia支持通过options和组合式API创建store,提供了更灵活的state管理和更简洁的语法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接:https://juejin.cn/post/7121209657678364685
Pinia官方:https://pinia.vuejs.org/zh/introduction.html

一、安装

yarn add pinia

npm install pinia

二、main.js 引入

import { createApp } from "vue"
import App from "./App.vue"
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount("#app")

三、创建 store

  • 可通过 defineStore 创建 多个 store (这与 vuex 只可以创建一个 store不同),所以 不再需要 modules(每个 store 便是一个模块)
  • 不再使用 mutations 作为 直接修改state 的方式
  • 支持以往的 options 创建形式,也可以使用 组合式函数定义一个store(像 setup 一样)

1、通过 options 创建

例如在 src下新建 piniaStore/storeA.js

import { defineStore } from "pinia";

export const storeA = defineStore("storeA", {
  state: () => {
    return {
      piniaMsg: "hello pinia",
    };
  },
  getters: {},
  actions: {},
})

2、通过组合式函数创建

  • ref() 就是 state 属性
  • computed() 就是 getters
  • function() 就是 actions
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }

  return { count, increment }
})

四、获取状态

1、在 <script setup> 中

<template>
  <div></div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

console.log(piniaStoreA.piniaMsg); //hello pinia
</script>

2、在 setup( ) 中

<script>
import { useCounterStore } from '../stores/counter'

export default defineComponent({
  setup() {
    const counterStore = useCounterStore()

    return { counterStore }
  },
  computed: {
    quadrupleCounter() {
      return this.counterStore.count * 2
    },
  },
  methods: {
    incrementAndPrint() {
      // 使用方法、状态,通过整个 store(因为没有解构)
      this.counterStore.increment()
      console.log('New Count:', this.counterStore.count)
    },
  },
})
</script>

五、修改状态

1、直接赋值修改

<template>
  <div>{{ piniaStoreA.piniaMsg }}</div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

console.log(piniaStoreA.piniaMsg); //hello pinia

piniaStoreA.piniaMsg = 'hello juejin'
console.log(piniaStoreA.piniaMsg); //hello juejin
</script>

2、使用 $patch 修改单个或多个状态

  • 可传入对象 修改
import { defineStore } from "pinia";

export const storeA = defineStore("storeA", {
  state: () => {
    return {
      piniaMsg: "hello pinia",
      name: "xiaoyue",
    };
  },
  getters: {},
  actions: {},
});
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()
console.log(piniaStoreA.name); //xiaoyue

piniaStoreA.$patch({
  piniaMsg: 'hello juejin',
  name: 'daming'
})

console.log(piniaStoreA.name);//daming
  • 也可传入 函数 修改
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

piniaStoreA.$patch((state) => {
  state.name = 'daming'
  state.piniaMsg = 'hello juejin'
})

3、在 actions 中进行修改

  • Pinia 去掉了 mutations,所以在 actions 中修改 state 就行
  • 使用 actions 时,像调用 methods 一样直接调用即可
import { defineStore } from "pinia";
export const storeA = defineStore("storeA", {
  state: () => {
    return {
      piniaMsg: "hello pinia",
      name: "xiao yue",
    };
  },
  actions: {
    setName(data) {
      this.name = data;
    },
  },
});
// script中使用
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

piniaStoreA.setName('daming')
<!-- 模板中使用 -->
<button @click="piniaStoreA.setName()">点击</button>

4、使用 $reset 重置 state

Pinia 可以使用 $reset 将状态 重置为初始值
需要注意的是,只有 选项式的store 才支持,组合函数形式的store不支持!

import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

piniaStoreA.$reset()

六、解构

在上述使用中,我们都是通过 整个 store 来使用内部的 state 等,怎么解构使用呢?

1、错误示范

传统的 ES6解构 会使 state 失去响应式

<template>
  <div>{{ name }}</div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

let { piniaMsg, name } = piniaStoreA

piniaStoreA.$patch({
  name: 'daming'    // 更新失败
})
</script>

2、正确方式

Pinia 提供了一个解构方法 storeToRefs

<template>
  <div>{{ name }}</div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
import { storeToRefs } from 'pinia'
let piniaStoreA = storeA()

let { piniaMsg, name } = storeToRefs(piniaStoreA)

piniaStoreA.$patch({
  name: 'daming'
})
</script>

七、getters

1、使用 getters

  • Pinia 中的 getters 和 Vuex 的 getters 用法是一致的, 也具有 缓存 特性
  • getter1 访问 getter2 时,通过 this
import { defineStore } from "pinia";

export const storeA = defineStore("storeA", {
  state: () => {
    return {
      count1: 1,
      count2: 2,
    };
  },
  getters: {
    sum (state) {
      console.log('我被调用了!')
      return state.count1 + state.count2;
    },
    sum2 () {
       // 访问其他 getter 时,通过this
       return this.sum + 1
    }
  },
});
<template>
  <div>{{ piniaStoreA.sum }}</div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()

console.log(piniaStoreA.sum) //3
</script>

2、 缓存验证

import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()
console.log(piniaStoreA.sum)
console.log(piniaStoreA.sum)
console.log(piniaStoreA.sum)
piniaStoreA.count1 = 2
console.log(piniaStoreA.sum)

在这里插入图片描述

八、辅助函数

若你更倾向于使用 选项式API,可以试试 Pinia 的 映射辅助函数,具体使用方式请 查看下一篇

PiniaVuex都是Vue.js中用于管理状态的库,但在设计和使用上有一些显著的区别: 1. **架构层级**:Vuex是基于应用的状态管理模式,它存在于整个单页面应用(SPA)的顶层。而PiniaVue 3.x引入的一个轻量级状态管理模式,它是专门为组件级别的状态管理设计的,更贴近于Composition API的思想。 2. **模块化**:Pinia鼓励小而专注的状态管理,通过分隔成一个个独立的store(即模块),每个store只关注特定业务领域。Vuex则是全局集中式的,所有状态都在一个store里,虽然可以通过分文件来组织,但不如Pinia那么精细。 3. **API设计**:Pinia的API更简洁,不需要手动创建actions、mutations等,直接通过`createStore`函数定义state和getter/setters即可。Vuex则需要显式地声明actions、mutations和getters,并通过commit和dispatch进行操作。 4. **性能**:由于Pinia的设计更为轻量级,它的开销相对较小,特别是在大型项目和性能敏感场景下。 5. **学习曲线**:Pinia的学习成本通常较低,因为它更接近于普通的JavaScript对象,开发者更容易理解和上手Vue 3推荐使用Pinia的原因包括: - 更好的组件内聚焦,利于解耦和维护。 - 简洁易用的API降低了复杂度,提高开发效率。 - 更贴合现代前端的趋势,如模块化、函数式编程思想。 - 长期看来,这可能是Vue团队对未来状态管理的一种优化方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值