新一代状态管理工具 Pinia学习,快速入门

基本介绍

Pinia 是 Vue.js 的轻量级状态管理库
官方网站:https://pinia.vuejs.org

  • pinia和vuex4一样,也是vue官方的状态管理工具(作者是 VueX 核心团队成员)
  • pinia相比vuex4,Pinia 对于 vue3 的兼容性更好
  • pinia相比vuex4,Pinia 具备完善的 TypeScript 类型推荐
  • pinia 同样支持 vue 开发者工具, 最新的开发者工具对vuex4支持不好
  • Pinia 的 API 设计非常接近 Vuex 5提案

pinia 核心概念

  • state: 状态
  • actions: 修改状态(包括同步和异步,pinia 中没有 mutations)
  • getters: 计算属性

基本使用与state

(1)安装

yarn add pinia
# 或
npm install pinia

(2)在 main.ts 中挂载 pinia

import { createApp } from 'vue'
import App from './App.vue'

+import { createPinia } from 'pinia'
+const pinia = createPinia()

createApp(App)
+  .use(pinia)
  .mount('#app')

(3)新建文件 store/counter.ts

import { defineStore } from 'pinia'

// 定义 Store, 命名建议: useXxxxStore
// 参数1:Store 的唯一标识
// 参数2:配置对象,可以提供 state actions getters
const useCounterStore = defineStore('counter', {
  // 相当于组件 data
  state() {
    return {
      count: 0,
    }
  },
  // 相当于组件 computed
  getters: {},
  // 相当于组件 methods
  actions: {},
})

// 导出 Store
export default useCounterStore

(4) 在组件中使用

<script setup lang="ts">
import useCounterStore from './store/counter'
// 使用 Store
const counter = useCounterStore()
</script>

<template>
  <h1>轻量状态管理库 Pinia</h1>
  <h2>Store:{{ counter }}</h2>
  <h2>状态 count:{{ counter.count }}</h2>
</template>

actions的使用

在 pinia中 没有mutations,只有 actions,不管是同步还是异步的代码,都可以在actions中完成。

(1)在actions中提供方法并且修改数据

import { defineStore } from 'pinia'
// 1. 创建store
// 参数1:store的唯一表示
// 参数2:对象,可以提供state actions getters
const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      count: 0,
    }
  },
+  actions: {
+    add() {
+      this.count++
+    },
+    addAsync() {
+      setTimeout(() => {
+        this.count++
+      }, 1000)
+    },
+  },
})

export default useCounterStore

(2)在组件中使用

<script setup>
import useCounterStore from './store/counter'

const counter = useCounterStore()
</script>

<template>
  <h1>根组件---{{ counter.count }}</h1>
  <button @click="counter.add">加1</button>
  <button @click="counter.addAsync">异步加1</button>
</template>

getters 的使用

pinia 中的 getters 和 vuex 中的基本是一样的,也带有缓存的功能

(1)在getters中提供计算属性

import { defineStore } from 'pinia'
// 1. 创建store
// 参数1:store的唯一表示
// 参数2:对象,可以提供 state actions getters
const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      count: 0,
    }
  },
+  getters: {
+    double(): number {
+      return this.count * 2
+    },
+  },
  actions: {
    add() {
      this.count++
    },
    addAsync() {
      setTimeout(() => {
        this.count++
      }, 1000)
    },
  },
})

export default useCounterStore

(2)在组件中使用

  <h1>根组件---{{ counter.count }}</h1>
  <h3>{{ counter.double }}</h3>

storeToRefs 的使用

目标:掌握storeToRefs的使用

如果直接从pinia中解构数据,会丢失响应式, 使用storeToRefs可以保证解构出来的数据也是响应式的

<script setup lang="ts">
import { storeToRefs } from 'pinia'
import useCounterStore from './store/counter'

const counter = useCounterStore()
// ❌ 如果直接从pinia中解构数据,会丢失响应式
// const { count, double } = counter

// ✅使用 storeToRefs 可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>

<template>
  <h1>轻量状态管理库 Pinia</h1>
  <h2>Store:{{ counter }}</h2>
  <h1>{{ count }}</h1>
  <h3>{{ double }}</h3>
  <hr />
  <button @click="counter.add">加1</button>
  <button @click="counter.addAsync">异步加1</button>
</template>

pinia 模块化

在复杂项目中,不可能吧多个模块的数据都定义到一个store中,一般来说会一个模块对应一个store,最后通过一个根store进行整合

(1)新建 store/user.ts 文件

import { defineStore } from 'pinia'

const useUserStore = defineStore('user', {
  state: () => {
    return {
      name: 'zs',
      age: 18,
    }
  },
})

export default useUserStore

(2)新建 store/index.ts

import useUserStore from './user'
import useCounterStore from './counter'

// 统一导出 useStore 方法
export default function useStore() {
  return {
    user: useUserStore(),
    counter: useCounterStore(),
  }
}

(3)在组件中使用

<script setup lang="ts">
import { storeToRefs } from 'pinia'
-import useCounterStore from './store/counter'
-const counter = useCounterStore()

+import useStore from './store'
+const { counter } = useStore()

// 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值