你懂 Pinia 的用法吗?

27 阅读4分钟

Vue 3.2 版本引入了一个新的状态管理库 Pinia,它是基于 Vue 3 Composition API 设计的,提供了一种简洁、直观的方式来管理应用程序的状态。下面我将介绍 Pinia 的用法之妙。

  1. 安装和配置:首先,使用 npm 或 yarn 安装 Pinia:
npm install pinia

然后,在您的应用程序的入口文件(如 main.js)中进行配置:

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

const app = createApp(App)
const pinia = createPinia()
app.use(pinia)

app.mount('#app')

通过 createPinia 创建一个全局的 Pinia 实例,并通过 app.use 将其安装到应用程序中。

  1. 定义和使用状态:在 Pinia 中,我们可以通过定义 store 来管理应用程序的状态。创建一个名为 CounterStore 的 store:
import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    }
  }
})

在上述代码中,我们使用 defineStore 函数来定义一个 store,并指定了一个唯一的 id 和 state 对象,state 对象中包含了应用程序的状态数据。同时,我们还可以定义 actions 来操作这些状态数据。

  1. 在组件中使用状态:在组件中使用 Pinia 的 store 很简单。只需通过 useStore 函数获取 store 的实例,并在模板和逻辑中使用它。
<template>
  <div>
    <p>Count: {{ counter.count }}</p>
    <button @click="counter.increment">Increment</button>
    <button @click="counter.decrement">Decrement</button>
  </div>
</template>

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

export default {
  setup() {
    const counter = useCounterStore()

    return {
      counter
    }
  }
}
</script>

通过 useCounterStore 获取 CounterStore 的实例,并在模板中绑定状态数据和方法。

  1. 在异步操作中使用状态:Pinia 还提供了方便的方式来处理异步操作。例如,我们可以在 actions 中定义异步的方法:
actions: {
  async fetchData() {
    try {
      const response = await fetch('https://api.example.com/data')
      const data = await response.json()
      
      // 更新状态
      this.data = data
    } catch (error) {
      console.error(error)
    }
  }
}

在上述代码中,我们使用了 async/await 来处理异步请求,并将返回的数据更新到状态中。

  1. 分模块管理状态:当应用程序变得复杂时,可以将不同的状态拆分为多个 store,并在需要的地方导入和使用它们。例如,我们可以创建一个名为 UserStore 的 store 来管理用户相关的状态:
import { defineStore } from 'pinia'

export const useUserStore = defineStore({
  id: 'user',
  state: () => ({
    user: null
  }),
  actions: {
    setUser(user) {
      this.user = user
    }
  }
})

然后,在组件中导入和使用 UserStore:

<script>
import { useUserStore } from './stores/user'

export default {
  setup() {
    const userStore = useUserStore()

    return {
      userStore
    }
  }
}
</script>

通过使用分模块的方式管理状态,可以更好地组织和维护应用程序的状态逻辑。

  1. 持久化存储:Pinia 还提供了持久化存储的功能,可以将状态数据保存在本地存储中,以便在页面刷新或重新加载后仍然保留状态。为了使用持久化存储,我们需要安装额外的插件。

首先,安装 pinia-plugin-persist 插件:

npm install pinia-plugin-persist

然后,在应用程序入口文件中进行配置:

import { createPinia } from 'pinia'
import { createPersist } from 'pinia-plugin-persist'

const pinia = createPinia()
pinia.use(createPersist({}))

通过导入 createPersist 函数并传递一个空对象来创建持久化存储插件。然后使用 pinia.use() 方法将插件安装到 Pinia 实例中。

接下来,在 store 中指定需要持久化的状态属性。在我们之前定义的 CounterStore 中添加如下代码:

export const useCounterStore = defineStore({
  // ...
  state: () => ({
    count: 0
  }),
  actions: {
    // ...
  },
  persist: true, // 启用持久化存储
  persistOptions: {
    // 配置持久化选项
    key: 'counter', // 存储键名
    paths: ['count'] // 指定需要持久化的状态属性
  }
})

在上述代码中,我们通过将 persist 属性设置为 true 来启用持久化存储,并使用 persistOptions 属性来配置持久化选项。在 persistOptions 中,我们可以指定存储的键名和需要持久化的状态属性。

现在,每当 CounterStore 的状态发生变化时,Pinia 会自动将指定的状态属性保存到本地存储中。在页面重新加载后,这些状态数据将被恢复。

  1. 使用插件扩展功能:除了持久化存储插件外,Pinia 还支持许多其他插件来扩展其功能。例如,pinia-plugin-axios 插件可以方便地集成 axios 库,处理异步请求。

首先,安装 pinia-plugin-axios 插件:

npm install pinia-plugin-axios

然后,在应用程序入口文件中进行配置:

import { createPinia } from 'pinia'
import { createAxiosPlugin } from 'pinia-plugin-axios'

const pinia = createPinia()
pinia.use(createAxiosPlugin(axios))

通过导入 createAxiosPlugin 函数并传递 axios 实例来创建 axios 插件。然后使用 pinia.use() 方法将插件安装到 Pinia 实例中。

接下来,我们可以在 store 中使用 axios 插件。例如,在之前定义的 UserStore 中添加如下代码:

export const useUserStore = defineStore({
  // ...
  actions: {
    async fetchUser(id) {
      const response = await this.$http.get(`/api/users/${id}`)
      const user = response.data
      this.setUser(user)
    }
  }
})