「从零开始的 Vue3 系列」:拥抱 Pinia - Vuex 的强劲对手解析与使用

92 阅读4分钟

前言

本系列将从零开始,系统性地介绍 Vue 3 的常用 API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握 Vue 3 的基础与进阶知识,最终具备独立搭建完整 Vue 3 项目的能力。

Pinia 对比vuex的优势

  • API 简洁性:Pinia 提供了更简单和直观的 API,使得状态管理的定义和使用更加容易理解。使用组合式 API 的方式,使得状态和方法更具可读性和维护性。
  • 类型支持更好:Pinia 天然支持 TypeScript,提供了更好的类型推断和自动完成支持,开发体验更佳。Vuex4 虽然也支持 TypeScript,但 Pinia 的实现让类型系统更加简洁和强大。
  • 模块化设计:与 Vuex 需要手动创建和组合模块不同,Pinia 使用可组合的 store,可以轻松地拆分和管理状态逻辑。每个 store 都是独立的模块,使用时更加灵活。
  • 轻量高效:Pinia 是围绕 Vue 3 的 Composition API 构建的,因此更加轻量和高效。它支持 tree-shaking,打包时只会包含使用到的部分。
  • 无 Mutation 概念:Pinia 取消了 Vuex 中的 Mutation 概念,直接在 actions 中修改状态。这种方式更符合开发者的直觉,也减少了样板代码的数量。
  • DevTools 支持:Pinia 具有良好的 Vue DevTools 集成,能够清晰地追踪状态的变化和调试应用程序。
  • 易于测试:由于 Pinia 的 API 更加函数式和模块化,测试变得更加简单和直接。

这些特性使得 Pinia 成为 Vue 3 项目中一种更现代和优雅的状态管理解决方案,尤其是在需要良好类型支持和更简洁代码的场合。

Pinia的使用

1. 安装 Pinia

	npm install pinia

2. 在 Vue 项目中引入 Pinia ---> main.js 中引入并注册 Pinia:

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

const app = createApp(App)

// 创建 Pinia 实例
const pinia = createPinia()

// 注册 Pinia
app.use(pinia)

app.mount('#app')

3. 定义一个 Store

Pinia 中的 store 与 Vuex 中的 module类似。你可以创建独立的 store 文件来管理不同的状态。以下是一个简单的 store 示例: 新增、删除、获取、修改等方法都是直接在actions中自己定义的

// stores/counter.js
//引入
import { defineStore } from 'pinia'

// 定义 Task Store
export const useTaskStore = defineStore('task', {
  state: () => ({
    tasks: [] // 任务列表,初始为空
  }),
  
  // 定义 actions 来处理新增、删除和获取任务
  actions: {
  	
  	// 新增任务
    addTask(task) {
      this.tasks.push(task) 
    },
    // 根据ID删除任
    removeTask(taskId) {
      this.tasks = this.tasks.filter(task => task.id !== taskId) 务
    },
    // 根据ID获取任务
    getTaskById(taskId) {
      return this.tasks.find(task => task.id === taskId) 
    }
  }
})

4. 在组件中使用 Store

在组件中,可以通过 useCounterStore 来访问和操作 store。 以下方法都是在store文件中的actions自己定义的,方法名按个人喜好 新增:通过调用 taskStore.addTask 方法将新任务添加到任务列表中。 删除:通过调用 taskStore.removeTask 方法,从任务列表中删除指定 ID 的任务。 获取:可以通过 taskStore.getTaskById(taskId) 来获取特定任务的信息。 修改同上

<template>
  <div>
    <h1>任务列表</h1>
    <ul>
      <li v-for="task in tasks" :key="task.id">
        {{ task.name }}
        <button @click="removeTask(task.id)">删除</button>
      </li>
    </ul>
    <input v-model="newTaskName" placeholder="输入新任务名称" />
    <button @click="addNewTask">添加任务</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

//这里引入的就是第三部定义的store文件
import { useTaskStore } from '@/stores/taskStore'

// 使用 Task Store
const taskStore = useTaskStore()

// 从 Store 中获取任务列表(获取数据直接使用taskStore.你要使用的数据,这个数据必须是你在store文件中的state定义了的)
const tasks = taskStore.tasks

// 本地状态用于输入新任务名称
const newTaskName = ref('')

// 添加新任务

function addNewTask() {
  if (newTaskName.value.trim()) {
    const newTask = {
      id: Date.now(), // 简单生成唯一ID
      name: newTaskName.value
    }
    //addTask这个方法就是新增
    taskStore.addTask(newTask)
    newTaskName.value = '' // 重置输入框
  }
}

// 删除任务
function removeTask(taskId) {
	//removeTask删除
  taskStore.removeTask(taskId)
}

</script>

这样,就可以通过 Pinia 实现数据的修改操作。

总结

Pinia 通过这些特性,提供了一个简洁、直观、功能强大的状态管理方案,非常适合 Vue 3 应用。 个人理解:把store中的state当成vue2中的data,把actions当成vue2中的methods,然后通过actions中定义的方法来操作数据。

ps:以上内容仅为本人对 vue3的个人理解,如有不足之处,欢迎大家指正与交流,共同进步。