大菠萝 Pinia 赶紧用起来

简介: 上次使用 Vuex4.0 的时候带来的体验不能说很差吧,可以说是非常不好,类型支持需要自定义等等问题让我将目光转向了社区中的新兴势力——Pinia

上次使用 Vuex4.0 的时候带来的体验不能说很差吧,可以说是非常不好,类型支持需要自定义等等问题让我将目光转向了社区中的新兴势力——Pinia

Pinia 是一个用于 Vue 的状态管理库,类似 Vuex, 是 Vue 的另一种状态管理方案 Pinia 支持 Vue2 和 Vue3

Pinia 对比 Vuex 的优势:

  • Pinia 的 API 设计非常接近 Vuex 5提案。(作者是 Vue 核心团队成员)
  • 无需像 Vuex 4 自定义复杂的类型来支持 typescript,天生具备完美的类型推断。
  • 模块化设计,你引入的每一个 store 在打包时都可以自动拆分他们。
  • 无嵌套结构,但你可以在任意的 store 之间交叉组合使用。
  • PiniaVue devtools 挂钩,不会影响 Vue 3 开发体验。

pinia 的使用架构如下

1682565282(1).png

从 Vuex 转 Pinia 简直不要太简单,下面来看一下 Pinia 的 Guide


store


pinia 中创建并挂载 pinia 的过程只有一步

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
createApp(App)
  .use(createPinia())
  .mount('#app')
复制代码

然后就可以开始定义 store 了,定义 store 的时候跟 Vuex 的 module 有些类似,但是不需要那么繁琐,定义不同的 store 模块然后直接在代码中引入使用即可。

定义一个 store 的方式如下

export default defineStore('count', {
  state: () => ({}),
  actions: {},
  getters: {}
})
复制代码

使用 store 时直接引入对应的 store 即可

<template>
  <div>{{ store.count }}</div>
  <div>{{ store.doubleCount }}</div>
  <button @click="store.increment">+</button>
</template>
<script setup lang="ts">
  import useCountStore from '../store/counter'
  const store = useCountStore()
</script>
复制代码

1682565308(1).png

在组件之外的其他地方使用 store

// 不要在函数之外使用 store
const store = useStore()
router.beforeEach((to, from, next) => {
  // we wanted to use the store here
  if (store.isLoggedIn) next()
  else next('/login')
})
// 在回调内部使用 store, 能保证 store 运行在它应该运行的地方
router.beforeEach((to) => {
  const store = useStore()
  if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
复制代码


state


state 用来存储数据状态,需要传入一个函数,并且将所有的 state 作为 object 返回。


import { defineStore } from 'pinia'
const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  },
  // 可以直接使用 state: () => ({})
})
// 直接使用 store 实例来范文 state
const store = useStore()
store.counter // 0
store.$reset() // 重置store状态
复制代码

更新 state

与 Vuex3.0不同的是,pinia 允许直接修改 state 的值,同时也提供了 patch 方法来同时更新多个 state

store.$patch({
  counter: store.counter + 1,
  name: 'Abalam',
})
复制代码

但是,使用此语法应用某些更改确实很困难或成本很高:任何集合修改(例如,从数组中推送、删除、拼接元素)都需要您创建一个新集合。正因为如此,该$patch方法还接受一个函数来对这种难以应用补丁对象的突变进行分组:

store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})
复制代码

覆盖 state

可以通过将商店的$state属性设置为新对象来替换商店的整个状态

store.$state = { counter: 666, name: 'Paimon' }
复制代码

订阅状态

可以通过$subscribe()一个 store的方法来观察 state 和它的变化,类似于 Vuex 的subscribe 方法。使用$subscribe()常规的优点watch()订阅只会在补丁后触发一次(例如,当使用上面的功能版本时)。

<template>
  <div>{{ store.count }}</div>
  <div>{{ store.name }}</div>
  <button @click="store.$patch({ count: 10, name: 'king' })">change</button>
</template>
<script setup lang="ts">
import useCountStore from '../store/counter'
const store = useCountStore()
store.$subscribe((mutation, state) => {
  console.log('store changed', state, mutation)
})
</script>
复制代码

每次 store 更新之后都会触发传入的回调,我们这里使用 dispath 来跟新多个 state 看一下效果

1682565344(1).png

默认情况下组件内的订阅将在组件卸载之后一同卸载,如果想将订阅保留可以传如第二个参数

const someStore = useSomeStore()
someStore.$subscribe(callback, true)
复制代码


getters


getters用于组合 state(计算值)

import { defineStore } from 'pinia'
export default defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    doubleCount(state) {
      return state.count * 2 // also use this.count
    }
  }
})
复制代码

getters也可以接收参数

import { defineStore } from 'pinia'
export default defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count += 1
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    },
    customMultiple(state) {
      return (multiple: number) => state.count * multiple
    }
  }
})
复制代码

1682565378(1).png

getters 可以使用其他 store 的 getters 作为条件计算

import useUserStore from './user'
getters: {
    doubleCount(state): string {
      const userStore = useUserStore()
      return `${state.count * 2}---${userStore.name}`
    },
    customMultiple(state) {
      return (multiple: number) => state.count * multiple
    }
  }
复制代码

getters 会自动推导返回的类型,但是由于可以使用其他store 的 getters,所以尽量手动标注这写 getters 的返回值类型


actions


actions 用于处理逻辑,他可以是异步的,在 action 函数内部使用 this 可以获取到 state 中的数据

export default defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count += 1
      throw new Error('error')
    }
  }
})
复制代码

同样的,actions 中也可以使用其他的 store 中的数据

actions 中也可以添加 state 中订阅的类似操作,当actions 触发时使用回调处理

const countStore = useCountStore()
countStore.$onAction(({ name, store, args, after, onError }) => {
  after((result) => console.log('after', result))
  onError((error) => console.error('onError', error))
  console.log('store action')
  console.log(name, store, args)
})
复制代码

1682565406(1).png

after钩子会在 action 执行完之后执行,当 action 抛出异常时会执行 onError 钩子

onAction 也会跟随组件销毁,同样可以让其在组件销毁时保留下来

someStore.$onAction(callback, true)

相关文章
echarts 柱状图/折线图x轴坐标间隔
echarts 柱状图/折线图x轴坐标间隔
1461 0
|
Linux 对象存储 Windows
MinIO 客户端安装与使用教程
MinIO 客户端安装与使用教程
1303 0
|
安全
Gitlab配置webhook报错:Urlis blocked: Requests to the local netwo..解决
Gitlab配置webhook报错:Urlis blocked: Requests to the local netwo..解决
1131 0
|
SQL 分布式计算 监控
全链路数据治理
本场景主要介绍以常见的真实的海量日志数据分析任务为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
|
5月前
|
存储 前端开发 应用服务中间件
Django 实战:静态文件与媒体文件从开发配置到生产部署
Django项目中,静态文件(Static Files)和媒体文件(Media Files)是两类不同用途的文件。本文详细介绍了它们的区别、配置方法以及在开发与生产环境中的处理方式,并结合用户头像上传功能进行实战演示,最后讲解了如何通过Nginx或OpenResty部署静态与媒体文件服务。
270 1
|
7月前
|
Kubernetes Ubuntu 容器
在Ubuntu上安装kubectl、kubeadm和kubelet
好了,你已经掌握了在Ubuntu上安装kubectl、kubeadm和kubelet的高超技艺。是时候展示你新召唤出的力量,像一位真正的烹饪大师一样,开始独特的佳肴烹饪之旅吧!
334 13
|
Kubernetes jenkins 持续交付
Jenkins 与 Kubernetes 的集成:实现高效的资源管理和自动化部署
【8月更文第31天】随着微服务架构的普及,Kubernetes 已经成为了容器编排的事实标准。Kubernetes 提供了一种强大的方式来管理容器化的应用程序,而 Jenkins 则是持续集成与持续部署(CI/CD)领域的一个重要工具。将 Jenkins 与 Kubernetes 集成,不仅可以充分利用 Kubernetes 的资源管理能力,还能通过 Jenkins 实现自动化构建、测试和部署,从而提高开发效率和部署速度。本文将详细介绍如何将 Jenkins 集成到 Kubernetes 环境中,并提供具体的代码示例。
1290 0
|
缓存 前端开发 JavaScript
npm 详解
npm 详解
923 2
|
jenkins Shell 持续交付
自动化部署:使用Jenkins和Docker实现CI/CD
【8月更文挑战第31天】 本文旨在引导读者了解如何通过Jenkins和Docker来实现持续集成和持续部署(CI/CD),从而优化开发流程,提升工作效率。文章将详细介绍配置Jenkins服务器、创建Docker镜像以及设置自动化构建和部署的步骤。通过实际操作案例,我们将展示如何将代码变更快速部署到测试或生产环境,确保软件质量与发布速度的双重保障。
1677 0
|
SQL 分布式计算 关系型数据库
Clickhouse时间日期函数一文详解+代码展示
Clickhouse时间日期函数一文详解+代码展示
3890 0
Clickhouse时间日期函数一文详解+代码展示