pinia的使用

最近在用vue3开发项目,项目里有用到pinia,就学习了一下,在这里主要是记录一下,下次可以看自己的笔记了!可以看官方文档哦!

1、pinia的简介

1.1pinia是什么

pinia 是一款新的vue3的状态管理库,完整的typescript支持。本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、 Redux一样);

1.2pinia的特点

  • 支持 vue2 和 vue3,两者都可以使用 pinia
  • 语法简洁,支持 vue3 中 setup 的写法,不必像 vuex 那样定义 statemutationsactionsgetters 等,可以按照 setupComposition API 的方式返回状态和改变状态的方法,实现代码的扁平化;
  • 支持 vuex 中 state、actions、getters 形式的写法,丢弃了 mutations,开发时候不用根据同步异步来决定使用 mutations 或 actions,pinia 中只有 actions;
  • 对 TypeScript 支持非常友好。
  • 允许你跨组件或页面共享状态。

1.3 与vuex的区别

  • Vuex 中核心部分: StateGettersMutations(同步) 和 Actions(异步)
  • Pinia 中核心部分: StateGetters 和 Actions(同步异步均支持)
  • mutation 已被弃用。它们经常被认为是极其冗余的。它们初衷是带来 devtools 的集成方案,但这已不再是一个问题了。
  • 与 Vuex 相比, Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API。
  • 与 TypeScript 一起使用时具有可靠的类型推断支持。

1.4 Pinia各部分作用

  • State 类似于组件中data,用于存储全局状态。
  • Getters 类似于组件中的computed,根据已有的State封装派生数据,也具有缓存的特性
  • Actions 类似于组件中的methods,用于封装业务逻辑,同步异步均可以。

2、store是什么

Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念stategetter 和 action,我们可以假设这些概念相当于组件中的 data、 computed 和 methods

2.1在什么时候使用Store

一个 Store 应该包含可以在整个应用中访问的数据。这包括在许多地方使用的数据,例如显示在导航栏中的用户信息,以及需要通过页面保存的数据,例如一个非常复杂的多步骤表单。

另一方面,你应该避免在 Store 中引入那些原本可以在组件中保存的本地数据,例如,一个元素在页面中的可见性。

并非所有的应用都需要访问全局状态,但如果你的应用确实需要一个全局状态,那 Pinia 将使你的开发过程更轻松。

3、Pinia的使用

3.1安装

yarn add pinia
# 或者使用 npm
npm install pinia

3.2创建一个 pinia 实例 (根 store) 并将其传递给应用

相当于mian.ts中使用

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')

3.3在项目中使用

  • src文件下创建一个store文件夹,并添加index.tsStore 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字,这个名字 ,也被用作 id ,是必须传入的
import { defineStore } from 'pinia'

// 你可以任意命名 `defineStore()` 的返回值,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。
// (比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {
  // 其他配置...
})
  • 你可以认为 state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。 
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

 3.3在页面中使用

store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value。就像 setup 中的 props 一样,我们不能对它进行解构

<script setup>
import { useCounterStore } from '@/stores/counter'
// 可以在组件中的任意位置访问 `store` 变量 ✨
const store = useCounterStore()
</script>

3.4从store解构。为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:

<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>

3.4state介绍

访问state

//默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。
const store = useStore()

store.count++

重置state

const store = useStore()

store.$reset()

在 $reset() 内部,会调用 state() 函数来创建一个新的状态对象,并用它替换当前状态。

在 Setup Stores 中,您需要创建自己的 $reset() 方法:

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)

  function $reset() {
    count.value = 0
  }

  return { count, $reset }
})

state 中数据的修改方式(actions和组件中)



<template>
  <h1>{{ store.count }}</h1>
  <h1>{{ store.info }}</h1>
  <hr />
  <h1>{{ count }}</h1>
  <h1>{{ info }}</h1>
  <p>
    <button @click="alertData">修改数据</button>
  </p>
</template>

<script lang="ts" setup>
import { toRefs } from 'vue'
import { storeToRefs } from 'pinia'
import { useCounterStore } from "@/store/useCounterStore ";
const store= useCounterStore ();
// 解构数据,但是得到的数据是不具有响应式的,只是一次性的
// 相当于仅仅只是...store而已,只是做了reactive处理,并没有做toRefs
// const { count, info } = store();
// 解决方法:
// 1. 通过使用toRefs函数,因为前面所说相当于是通过reactive处理,因此可以
// const { count, info } = toRefs(store);
// 2. 通过pinia中提供的storeToRefs方法来解决,推荐使用
const { count, info } = storeToRefs(store);
const alertData = () => {
  // 方式一:最简单的方法,如下
  // 解构后更改方式
  // count.value += 10
  // 结构前更改方式
  // store.count += 10
  // 方式二:若要同时修改多个数据,建议使用$patch来实现批量更新,在内部做了优化
  // store.$patch({
  //   count: store.count + 1,
  //   info: "hello"
  // })
  // 方式三:更好的批量更新方法,通过$patch传递一个函数来实现,这里的state就是useMainStore容器中的state
  store.$patch(state => {
    state.count += 10
    state.info = "pinia批量更新"
  })
}

</script>

<style>
</style>

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起名时在学Aiifox

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值