Vue状态管理库Pinia详解

Pinia 是 Vue 的状态管理库,它提供了一种更简单、更不规范的 API 来管理应用的状态。Pinia 的设计哲学是简单性和易用性,它避免了 Vuex 中的许多复杂概念,如 mutations 和模块的嵌套结构,提供了一种更现代、更符合 Vue 3 Composition API 风格的状态管理方式。

先来瞅一眼 Pinia 的核心组件主要包括以下几个方面:

  1. Store:Pinia 中的 Store 是一个保存状态和业务逻辑的实体,它不与组件树绑定,可以在整个应用中访问。Store 包含三个核心概念:state(状态)、getters(获取器)、actions(动作)。这些概念类似于组件中的 data、computed 和 methods。

  2. defineStore() :这是定义 Store 的函数,需要传入一个独一无二的名字作为 ID,用于连接 Store 和 devtools。Store 可以通过 Setup 函数或 Option 对象来定义。

  3. reactive:虽然 Pinia 本身不要求使用 Composition API,但它与 Vue 的 reactive 系统紧密集成,允许开发者以声明式的方式管理状态。

  4. Devtools 支持:Pinia 支持 Vue Devtools,提供了追踪 actions 和 mutations 的时间线、时间旅行和热更新等功能,方便开发者调试。

  5. 插件系统:Pinia 允许通过插件来扩展其功能,例如支持服务器端渲染或添加额外的中间件。

  6. TypeScript 支持:Pinia 提供了对 TypeScript 的良好支持,包括类型推断和自动补全功能,使得在 TypeScript 项目中使用 Pinia 更加方便 。

  7. SSR 支持:Pinia 支持服务端渲染,这对于构建需要 SSR 的应用是一个重要的特性。

  8. 映射辅助函数:Pinia 提供了如 mapStores、mapState 和 mapActions 等辅助函数,使得在组件中使用 Store 更加方便。

下面是每个部分的详细介绍。

1. Store

在 Pinia 中,Store 是用来封装应用的状态和逻辑的核心概念。它允许你将状态和行为集中管理,而不是分散在各个组件中。Store 可以包含以下几部分:

  • state:状态数据,通常是响应式的,可以在组件中被读取和修改。
  • getters:计算属性,用于派生状态,它们是响应式的,并且可以被缓存。
  • actions:可以包含任意的异步操作或同步操作,用于修改状态或执行复杂的业务逻辑。

案例实现

下面是一个创建 Store 的步骤解析,包括代码示例:

步骤 1: 定义 Store

首先,你需要从 Pinia 导入 defineStore 函数,并使用它来定义一个新的 Store

javascript 复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    users: [] // 初始状态是一个空数组
  }),
  getters: {
    // 一个 getter 函数,返回数组中的用户数量
    count: (state) => state.users.length
  },
  actions: {
    // 一个 action 函数,用于添加用户
    addUser(user) {
      this.users.push(user)
    }
  }
})

步骤 2: 在组件中使用 Store

在 Vue 组件中,你可以通过调用你定义的 useUserStore 函数来使用这个 Store

html 复制代码
<template>
  <div>
    <button @click="addNewUser">添加用户</button>
    <p>用户总数: {{ userCount }}</p>
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import useUserStore from '@/stores/user'

const store = useUserStore()
const users = computed(() => store.users)
const userCount = computed(() => store.count)

function addNewUser() {
  store.addUser({ id: Date.now(), name: '新用户' })
}
</script>

代码解析

  • 导入 defineStore :从 Pinia 导入 defineStore 函数来定义新的 Store
  • 定义 useUserStore :创建一个名为 useUserStore 的函数,它返回一个 Store 对象。
  • state :在 Store 中定义了一个状态 users,初始为空数组。
  • getters :定义了一个 count getter,它返回 users 数组的长度。
  • actions :定义了一个 addUser action,它接受一个用户对象并将其添加到 users 数组中。
  • 在组件中使用 :在组件的 <script setup> 块中,通过调用 useUserStore 来获取 Store 实例,并使用 computed 来创建响应式的 usersuserCount
  • 添加用户 :定义了一个 addNewUser 函数,当按钮被点击时,调用 store.addUser 来添加新用户。

以上案例展示了如何在 Pinia 中创建和管理状态,以及如何在 Vue 组件中使用 Store。通过这种方式,你可以集中管理状态,使得状态逻辑更加清晰和可维护。

2. defineStore()

defineStore() 是 Pinia 中用于定义 Store 的函数。它允许你以声明式的方式创建一个状态管理单元,这个单元可以包含状态(state)、获取器(getters)、动作(actions)等。defineStore() 函数接受一个唯一的 ID 和一个配置对象,配置对象中可以定义 state、getters、actions 等属性。

案例实现

下面是一个使用 defineStore() 创建 Store 的步骤解析,包括代码示例:

步骤 1: 导入 defineStore

首先,需要从 Pinia 导入 defineStore 函数。

javascript 复制代码
import { defineStore } from 'pinia'

步骤 2: 定义 Store

使用 defineStore() 定义一个新的 Store,传入一个唯一的 ID 和一个配置对象。

javascript 复制代码
export const useCartStore = defineStore('cart', {
  state: () => ({
    items: [] // 购物车初始状态为空数组
  }),
  getters: {
    // 计算属性,返回购物车中商品的总数量
    itemCount(state) {
      return state.items.reduce((total, item) => total + item.quantity, 0)
    }
  },
  actions: {
    // 添加商品到购物车的动作
    addItem(item) {
      const index = this.items.findIndex(i => i.id === item.id)
      if (index > -1) {
        // 如果商品已存在,则增加数量
        this.items[index].quantity += item.quantity
      } else {
        // 否则,添加新商品
        this.items.push(item)
      }
    },
    // 清空购物车的动作
    clearCart() {
      this.items = []
    }
  }
})

步骤 3: 在组件中使用 Store

在 Vue 组件中,通过调用 useCartStore 来使用这个 Store。

html 复制代码
<template>
  <div>
    <button @click="addItem">添加商品</button>
    <button @click="clearCart">清空购物车</button>
    <p>商品总数: {{ itemCount }}</p>
    <ul>
      <li v-for="item in cartItems" :key="item.id">
        {{ item.name }} - 数量: {{ item.quantity }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import useCartStore from '@/stores/cart'

const store = useCartStore()
const cartItems = computed(() => store.items)
const itemCount = computed(() => store.itemCount)

function addItem() {
  store.addItem({ id: 1, name: '商品A', quantity: 1 })
}

function clearCart() {
  store.clearCart()
}
</script>

代码解析

  • 导入 defineStore :从 Pinia 导入 defineStore 函数。
  • 定义 useCartStore :创建一个名为 useCartStore 的函数,它返回一个配置好的 Store 对象。
  • state :在 Store 中定义了一个状态 items,初始为空数组,用于存储购物车中的商品。
  • getters :定义了一个 itemCount getter,它通过遍历 items 数组并累加每个商品的 quantity 来计算总数量。
  • actions :定义了 addItemclearCart 两个 actions。addItem 用于向购物车添加商品,如果商品已存在则增加其数量;clearCart 用于清空购物车。
  • 在组件中使用 :在组件的 <script setup> 块中,通过调用 useCartStore 来获取 Store 实例,并使用 computed 来创建响应式的 cartItemsitemCount
  • 添加和清空商品 :定义了 addItemclearCart 函数,分别用于添加商品和清空购物车。

使用 defineStore() 创建一个包含状态、获取器和动作的 Store,并在 Vue 组件中使用这个 Store 来管理购物车的状态。通过这种方式,你可以将状态逻辑封装在 Store 中,使得组件更加简洁和易于管理。

3. reactive

reactive() 是 Vue 3 的 Composition API 中的一个函数,它用于创建响应式的状态对象。当使用 reactive() 创建一个对象后,Vue 会追踪这个对象中属性的读取和修改,并且在数据变化时通知依赖于这些数据的组件重新渲染。

Pinia 与 Vue 的响应式系统紧密集成,reactive() 通常在定义 Store 的状态时使用。在 Pinia 中,状态(state)是一个通过 reactive() 创建的响应式对象,因此任何对状态的修改都会自动触发与该状态相关的组件更新。

案例实现

下面是一个使用 reactive() 来创建响应式状态的步骤解析:

步骤 1: 导入 reactive

首先,需要从 Vue 导入 reactive 函数。

javascript 复制代码
import { reactive } from 'vue'

步骤 2: 使用 reactive 创建状态

使用 reactive() 函数来创建一个响应式的状态对象。

javascript 复制代码
const state = reactive({
  count: 0, // 初始状态
  message: 'Hello, Pinia!' // 初始消息
})

步骤 3: 在 Pinia Store 中使用 reactive 状态

在 Pinia 的 defineStore() 中,可以直接使用 reactive() 来定义状态。

javascript 复制代码
import { defineStore } from 'pinia'
import { reactive } from 'vue'

export const useMyStore = defineStore('myStore', {
  state: () => reactive({
    count: 0,
    message: 'Hello, Pinia!'
  }),
  // 其他 getters 和 actions 可以在这里定义
})

步骤 4: 在组件中使用 Store

在 Vue 组件中,通过调用 useMyStore 来使用这个 Store,并访问响应式状态。

html 复制代码
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Message: {{ message }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import useMyStore from '@/stores/myStore'

const store = useMyStore()
const count = computed(() => store.state.count)
const message = computed(() => store.state.message)

function increment() {
  store.state.count++
}
</script>

代码解析

  • 导入 reactive :从 Vue 导入 reactive 函数。
  • 创建响应式状态 :使用 reactive() 创建一个包含 countmessage 的响应式状态对象。
  • 在 Pinia Store 中使用 reactive :在 defineStore()state 函数中返回一个 reactive() 对象,这样 Pinia 就可以管理这个状态的响应性。
  • 在组件中使用 :在组件的 <script setup> 块中,通过调用 useMyStore 来获取 Store 实例。使用 computed 来确保访问状态时保持响应性。
  • 修改状态 :定义了一个 increment 函数,当按钮被点击时,直接修改 store.state.count,这会触发组件的更新。

通过这种方式,你可以确保状态的任何变化都会自动传播到使用这些状态的组件中,实现响应式的数据流,你get到了吗。

4. Devtools 支持

Vue Devtools 是一个浏览器扩展,它为开发 Vue 应用提供了强大的调试支持。对于 Pinia 来说,Devtools 支持意味着你可以在开发过程中更直观地查看和操作应用的状态。

Pinia 与 Vue Devtools 集成,提供了以下功能:

  • 状态查看:可以在 Devtools 中查看所有 Pinia Store 的状态。
  • 时间旅行:回溯状态的历史,查看状态的变化过程。
  • 动作追踪:记录和展示 Store 中 actions 的调用历史,包括参数和执行时间。
  • 状态修改:允许你在 Devtools 中直接修改状态,这些修改会实时反映到应用中。
  • 持久化状态:在开发过程中保持状态不变,即使页面刷新或组件重新渲染。

案例实现

要充分利用 Pinia 的 Devtools 支持,你需要确保正确安装和配置了 Vue Devtools,并且正确地在你的 Pinia Store 中编写代码。来吧,一步一步跟着做就行:

步骤 1: 安装 Vue Devtools

首先,确保你已经安装了 Vue Devtools 浏览器扩展。你可以从 Chrome Web Store 或 Firefox Add-ons 等地方安装。

步骤 2: 创建 Pinia Store

创建一个 Pinia Store,并定义 state、getters 和 actions。

javascript 复制代码
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    }
  }
})

步骤 3: 在 Vue 应用中使用 Pinia

在你的 Vue 应用中创建 Pinia 实例,并在应用启动时使用它。

javascript 复制代码
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')

步骤 4: 使用 Store

在组件中使用你的 Store,并执行一些状态更改的动作。

html 复制代码
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import useCounterStore from '@/stores/counter'

const store = useCounterStore()
const count = computed(() => store.count)

function increment() {
  store.increment()
}
</script>

步骤 5: 使用 Vue Devtools 调试

  • 打开浏览器的开发者工具。
  • 切换到 Vue Devtools 面板。
  • 在"Components"或"Store"标签页中,你应该能看到你的 Pinia Store。
  • 展开 Store,查看 state、getters 和 actions。
  • 点击 actions,你可以看到它们的调用历史和参数。
  • 直接在 Devtools 中修改 state 的值,看应用如何响应这些变化。

代码过程步骤解析

  • 安装 Devtools:确保浏览器扩展已安装。
  • 创建 Store :使用 defineStore 创建一个包含 state、getters 和 actions 的 Pinia Store。
  • 应用配置:在应用启动时创建 Pinia 实例并使用它。
  • 组件使用:在组件中通过调用 Store 函数来获取 Store 实例,并使用 computed 属性来保持响应性。
  • 调试:使用 Vue Devtools 查看和修改状态,追踪 actions。

利用 Vue Devtools 提供的功能来调试使用 Pinia 管理状态的 Vue 应用,感觉是不是挺爽。

5. 插件系统

Pinia 的插件系统允许开发者扩展 Pinia 的功能。插件可以访问 Pinia 的 Store 创建过程,可以执行以下操作:

  • 在 Store 创建之前或之后执行自定义逻辑。
  • 拦截 Store 的 stategettersactions 等属性。
  • 向 Store 添加自定义属性或方法。
  • 处理 Store 的销毁逻辑。

Pinia 插件通常在创建 Pinia 实例时注册,然后 Pinia 会将插件应用到每个创建的 Store 上。

案例实现

下面是一个创建和使用 Pinia 插件的步骤解析,包括代码示例:

步骤 1: 定义插件

首先,定义一个插件函数,该函数接收 Pinia 的实例作为参数。

javascript 复制代码
function myPiniaPlugin(pinia) {
  // 插件逻辑
}

步骤 2: 插件逻辑

在插件函数内部,可以访问 Pinia 的 store 对象,并对其进行操作。

javascript 复制代码
function myPiniaPlugin(pinia) {
  pinia.use((store) => {
    // 可以在此处访问 store.state, store.getters, store.actions 等
    // 例如,向 store 添加一个新属性
    store.myCustomProperty = 'Hello from plugin!'
  })
}

步骤 3: 创建 Pinia 实例并使用插件

创建 Pinia 实例时,使用 use 方法注册插件。

javascript 复制代码
import { createPinia } from 'pinia'

const pinia = createPinia().use(myPiniaPlugin)

步骤 4: 创建 Store

定义一个 Store,使用 defineStore 函数。

javascript 复制代码
import { defineStore } from 'pinia'

export const useMyStore = defineStore('myStore', {
  // state, getters, actions 定义
  state: () => ({
    value: 0
  }),
  // 其他选项...
})

步骤 5: 在组件中使用 Store

在组件中使用 Store,并访问插件添加的属性。

html 复制代码
<template>
  <div>
    <p>Value: {{ value }}</p>
    <p>Plugin Property: {{ store.myCustomProperty }}</p>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import useMyStore from '@/stores/myStore'

const store = useMyStore()
const value = computed(() => store.value)
</script>

步骤 6: 组件中使用插件属性

在组件的模板或脚本中,使用插件添加到 Store 的自定义属性。

html 复制代码
// 在模板中
<p>Plugin Property: {{ store.myCustomProperty }}</p>

// 在脚本中
console.log(store.myCustomProperty) // 输出: Hello from plugin!

代码过程步骤解析

  • 定义插件:创建一个函数,该函数接收 Pinia 实例并定义插件逻辑。
  • 插件逻辑 :在插件函数内部,使用 pinia.use 方法注册一个回调,该回调接收每个 Store 并可以对其进行操作。
  • 注册插件 :在创建 Pinia 实例时,通过 .use() 方法注册插件。
  • 创建 Store :使用 defineStore 定义 Store,包括 state、getters、actions。
  • 使用 Store:在组件中使用 Store,并利用 computed 属性保持响应性。
  • 访问插件属性:在组件的模板或脚本中,访问插件添加到 Store 的自定义属性。

记住这一点,开发者需要添加自定义逻辑和属性,通过Pinia 插件系统就 OK。

6. TypeScript 支持

Pinia 为 TypeScript 用户提供了一流的支持,确保类型安全和开发体验。Pinia 的 TypeScript 支持主要体现在以下几个方面:

  1. 类型推断:Pinia 利用 TypeScript 的高级类型系统来推断 Store 中的状态、getters 和 actions 的类型。
  2. 类型声明 :Pinia 提供了类型声明文件(.d.ts),确保 Pinia API 在 TypeScript 项目中的类型正确性。
  3. 自动补全:在 TypeScript 环境中,编辑器可以提供自动补全功能,帮助开发者快速编写代码。
  4. 类型守卫:Pinia 与 TypeScript 配合使用时,可以利用类型守卫来确保对 Store 属性的访问是安全的。

案例实现

下面是一个使用 TypeScript 与 Pinia 结合使用的步骤解析,包括代码示例:

步骤 1: 设置 TypeScript 环境

确保你的项目已经配置了 TypeScript,并且安装了必要的类型声明文件。

bash 复制代码
npm install typescript @vue/compiler-sfc

步骤 2: 定义 Store 使用 TypeScript

使用 TypeScript 的类型定义来创建 Pinia Store。

typescript 复制代码
import { defineStore } from 'pinia'

interface State {
  count: number
  message: string
}

export const useMyStore = defineStore('myStore', {
  state: (): State => ({
    count: 0,
    message: 'Hello, Pinia with TypeScript!'
  }),
  getters: {
    // 使用 TypeScript 来声明 getter 的返回类型
    doubleCount: (state): number => state.count * 2
  },
  actions: {
    increment(): void {
      this.count++
    }
  }
})

步骤 3: 在组件中使用 Store

在 Vue 组件中使用 Store,并利用 TypeScript 提供类型安全。

html 复制代码
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Message: {{ message }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import useMyStore from '@/stores/myStore'

const store = useMyStore()
const count = computed(() => store.count)
const message = computed(() => store.message)
const doubleCount = computed(() => store.doubleCount)

function increment() {
  store.increment()
}
</script>

步骤 4: 利用类型守卫

使用类型守卫来确保对 Store 属性的访问是安全的。

typescript 复制代码
if (store.hasOwnProperty('count')) {
  // TypeScript 知道 'count' 存在且为 number 类型
  console.log(store.count)
}

代码过程步骤解析

  • 配置 TypeScript:确保项目中安装了 TypeScript 及其类型声明文件。
  • 定义 Store 类型 :使用 TypeScript 的接口(interface)来定义 Store 的状态类型。
  • 创建 Store :使用 defineStore 并传入类型化的 state 函数,以及声明了返回类型的 getters 和 actions。
  • 组件中使用 Store:在组件中使用 TypeScript 来确保访问 Store 属性的类型安全。
  • 类型守卫 :使用 TypeScript 的 hasOwnProperty 方法和类型守卫来安全地访问 Store 的属性。

小结一下,Pinia 与 TypeScript 结合使用可以提供类型安全的状态管理,同时编辑器的自动补全和类型检查功能可以提高开发效率和减少错误。

7. SSR 支持

服务器端渲染(SSR)是一种将网站页面在服务器上生成并发送给客户端的技术。对于状态管理库来说,SSR 支持意味着可以在服务器上初始化和操作状态,然后将状态序列化后发送到客户端,客户端再将这些状态恢复以保持与服务器端相同的状态。

Pinia 对 SSR 的支持主要体现在以下几个方面:

  1. 状态序列化:Pinia 允许将状态(state)序列化成 JSON 字符串,以便在服务器和客户端之间传输。
  2. 状态恢复:客户端可以接收服务器端的状态,并将其恢复到对应的 Store 中。
  3. 无状态的 Store 定义:Pinia 的 Store 定义是无状态的,这意味着在服务器端和客户端端都可以重新创建 Store。
  4. 与 Vue SSR 的集成:Pinia 可以与 Vue 的 SSR 系统集成,确保在服务器端预渲染组件时使用正确的状态。

案例实现

下面是一个使用 Pinia 进行 SSR 的步骤解析,包括代码示例:

步骤 1: 定义 Store

首先,定义一个 Pinia Store。

javascript 复制代码
import { defineStore } from 'pinia'

export const useMyStore = defineStore('myStore', {
  state: () => ({
    count: 0
  }),
  // 其他选项...
})

步骤 2: 在服务器端创建和序列化状态

在服务器端,创建 Store 实例并初始化状态,然后将状态序列化。

javascript 复制代码
// server.js
import { createPinia } from 'pinia'
import useMyStore from '@/stores/myStore'

const pinia = createPinia()

// 模拟从数据库获取初始状态
const initialState = { count: 10 }

// 创建 Store 实例并设置初始状态
const store = useMyStore(pinia)
store.$state.count = initialState.count

// 序列化状态
const stateToTransfer = JSON.stringify(store.$state)

步骤 3: 在客户端恢复状态

在客户端,接收服务器端发送的状态,然后恢复到对应的 Store 中。

javascript 复制代码
// client.js
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue' // Vue 应用的根组件
import useMyStore from '@/stores/myStore'

const pinia = createPinia()

// 假设从服务器接收的状态如下
const stateFromServer = JSON.parse(/* state serialized from server */)

// 创建 Store 实例并恢复状态
const store = useMyStore(pinia)
store.$state.count = stateFromServer.count

const app = createApp(App)
app.use(pinia)
app.mount('#app')

步骤 4: 在 Vue 组件中使用 Store

在 Vue 组件中,像平常一样使用 Store。

html 复制代码
<template>
  <div>{{ count }}</div>
</template>

<script setup>
import { computed } from 'vue'
import useMyStore from '@/stores/myStore'

const store = useMyStore()
const count = computed(() => store.count)
</script>

代码过程步骤解析

  • 定义 Store :使用 defineStore 定义一个 Pinia Store。
  • 服务器端创建和序列化 :在服务器端,创建 Store 实例,设置初始状态,并使用 JSON.stringify 序列化状态。
  • 客户端恢复状态 :在客户端,解析服务器端发送的状态字符串,并恢复到 Store 的 $state 中。
  • 组件中使用 Store:在 Vue 组件中,通过调用 Store 函数获取 Store 实例,并使用 computed 属性来访问状态。

一句话,Pinia支持SSR有助于提高应用的初始加载性能和SEO优化。

8. 映射辅助函数

在 Pinia 中,映射辅助函数用于将 Store 中的状态(state)、获取器(getters)、动作(actions)映射到组件的计算属性(computed properties)、方法(methods)或响应式属性上。这些辅助函数提供了一种便捷的方式来使用 Store,而无需在每个组件中重复编写相同的代码。

Pinia 的映射辅助函数主要包括:

  • mapState:将 Store 中的状态映射为组件的计算属性。
  • mapGetters:将 Store 中的获取器映射为组件的计算属性。
  • mapActions:将 Store 中的动作映射为组件的方法。

案例实现

下面是一个使用 Pinia 映射辅助函数的步骤解析,包括代码示例:

步骤 1: 定义 Store

首先,定义一个 Pinia Store。

javascript 复制代码
import { defineStore } from 'pinia'

export const useCartStore = defineStore('cart', {
  state: () => ({
    items: []
  }),
  getters: {
    itemCount: (state) => state.items.length
  },
  actions: {
    addItem(item) {
      this.items.push(item)
    }
  }
})

步骤 2: 使用映射辅助函数

在组件中,使用 mapStatemapGettersmapActions 将 Store 的属性映射到组件上。

html 复制代码
<template>
  <div>
    <p>Item Count: {{ itemCount }}</p>
    <button @click="addItem({ id: 1, name: 'Apple' })">Add Apple</button>
  </div>
</template>

<script setup>
import { mapState, mapGetters, mapActions } from 'pinia'
import useCartStore from '@/stores/cart'

const store = useCartStore()

// 使用 mapState 映射状态
const items = mapState(store, 'items')

// 使用 mapGetters 映射获取器
const itemCount = mapGetters(store, 'itemCount')

// 使用 mapActions 映射动作
const { addItem } = mapActions(store, ['addItem'])
</script>

步骤 3: 在模板中使用映射的属性

在组件的模板中,直接使用映射的计算属性和方法。

html 复制代码
<p>Item Count: {{ itemCount }}</p>
<button @click="addItem({ id: 1, name: 'Apple' })">Add Apple</button>

代码过程步骤解析

  • 定义 Store :使用 defineStore 定义一个包含状态、获取器和动作的 Pinia Store。
  • 使用映射辅助函数
    • mapState:将 items 状态映射为组件的计算属性。
    • mapGetters:将 itemCount 获取器映射为组件的计算属性。
    • mapActions:将 addItem 动作映射为组件的方法。
  • 模板中使用 :在模板中,使用映射的计算属性 itemCount 来显示项目数量,使用映射的方法 addItem 来添加新项目。

使用映射辅助函数,Pinia 可以让开发者以声明式的方式在组件中使用 Store 的状态和行为,从而减少样板代码并提高组件的可读性和可维护性。此外,这些辅助函数还有助于保持响应性,确保当 Store 中的状态变化时,组件能够自动更新。

最后

不得不说,Pinia 提供了一种灵活且高效的方式来管理 Vue 应用的状态,无论是在单页应用还是服务器端渲染的场景下,都有出色的表现,写完收工,欢迎关注威哥爱编程,一起走全栈之路。

相关推荐
石小石Orz2 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
小行星1254 分钟前
前端预览pdf文件流
前端·javascript·vue.js
join85 分钟前
解决vue-pdf的签章不显示问题
javascript·vue.js·pdf
小行星12511 分钟前
前端把dom页面转为pdf文件下载和弹窗预览
前端·javascript·vue.js·pdf
Lysun00120 分钟前
[less] Operation on an invalid type
前端·vue·less·sass·scss
土豆湿27 分钟前
拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
开发语言·javascript·css
J总裁的小芒果35 分钟前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
Lei_zhen9638 分钟前
记录一次electron-builder报错ENOENT: no such file or directory, rename xxxx的问题
前端·javascript·electron
辣条小哥哥39 分钟前
electron主进程和渲染进程之间的通信
javascript·electron·ecmascript
咖喱鱼蛋40 分钟前
Electron一些概念理解
前端·javascript·electron