Vue 小白入门|Pinia 核心用法全解

📌 前言

Pinia 是 Vue 官方推荐的新一代状态管理库,完美替代 Vuex,用法更简洁、轻量化,无复杂配置,可以快速上手!

一、先准备一个演示效果

我们将实现两个小案例,贯穿整个 Pinia 知识点:

  • 数字求和计算器
  • 土味情话列表(接口获取 + 本地存储持久化)

二、快速搭建 Pinia 环境

csharp 复制代码
# 安装 Pinia(Vue3 专用)
npm i pinia

main.ts 引入并挂载(必须做)

csharp 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
app.use(createPinia()) // 挂载 Pinia
app.mount('#app')

三、Pinia 核心概念(3 个秒懂)

每个 Store 对应一个全局数据模块,包含 3 个核心:

  • state → 存储数据(相当于组件 data)
  • getters → 计算属性(相当于组件 computed)
  • actions → 业务方法(相当于组件 methods)

四、定义 Store(存储 + 读取数据)

1. 数字计算器 Store src/store/count.ts

csharp 复制代码
// 引入defineStore创建store
import { defineStore } from 'pinia'

// 第一个参数:当前store的唯一标识(不能重复)
// 第二个参数:store配置项
export const useCountStore = defineStore('count', {
  // 真正存储数据的地方(必须用函数返回,避免数据污染)
  state: () => ({
    sum: 6 // 要存储的求和数字
  }),

  // 计算属性:基于state加工数据
  getters: {
    doubleSum(state) {
      return state.sum * 2
    }
  },

  // 方法:处理业务逻辑、修改state
  actions: {
    increment() {
      // this指向当前store实例
      this.sum++
    }
  }
})

2. 情话列表 Store src/store/talk.ts

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

export const useTalkStore = defineStore('loveTalk', {
  state: () => ({
    // 存储土味情话列表
    loveTalk: [
      { id: 1, title: '今天你有点怪,哪里怪,怪好看的!' },
      { id: 2, title: '草莓、蓝莓、蔓越莓,今天你想我了没?' },
      { id: 3, title: '心里给你留了一块地,我的死心塌地' }
    ]
  })
})

五、修改数据的 3 种方式(高频考点)

方式 1:直接修改(最简单)

csharp 复制代码
// 先引入store
const countStore = useCountStore()
// 直接修改state数据
countStore.sum = 666

方式 2:批量修改($patch

适合一次性修改多个数据,性能更优

csharp 复制代码
countStore.$patch({
  sum: 888,
  school: '清华大学'
})

方式 3:通过 action 修改(推荐)

适合带业务逻辑的修改,可传参、写异步 / 同步逻辑

csharp 复制代码
// store中定义带参数的action
actions: {
  increment(val: number) {
    this.sum += val
  }
}

// 组件中使用
const n = ref(1)
countStore.increment(n.value)

六、storeToRefs 让模板更简洁

作用 : 将 store 中的state/getters转为ref对象,直接解构在模板中使用不用写store.xxx
关键注意

  • Pinia 的storeToRefs只转换数据(state/getters),不转换方法
  • Vue 的toRefs:会转换 store 所有内容,不推荐用
csharp 复制代码
<template>
  <div class="count">
    <!-- 直接用解构后的sum,简洁易懂 -->
    <h2>当前求和为:{{ sum }}</h2>
  </div>
</template>

<script setup lang="ts" name="Count">
import { useCountStore } from '@/store/count'
// 引入pinia提供的storeToRefs
import { storeToRefs } from 'pinia'

// 获取store实例
const countStore = useCountStore()
// 转换后解构数据
const { sum } = storeToRefs(countStore)
</script>

七、getters 计算属性详解

作用 :当state中的数据需要加工后再使用 时,用 getters(缓存计算结果,性能更高)

csharp 复制代码
export const useCountStore = defineStore('count', {
  state: () => ({
    sum: 6,
    school: 'beijing university'
  }),

  getters: {
    // 写法1:常规函数(可通过state访问数据)
    doubleSum(state) {
      return state.sum * 2
    },

    // 写法2:箭头函数(更简洁)
    doubleSum2: state => state.sum * 2,

    // 复杂计算:转大写
    upperSchool(state) {
      return state.school.toUpperCase()
    }
  }
})

组件中使用:

csharp 复制代码
<h2>放大两倍:{{ countStore.doubleSum }}</h2>
<h2>学校大写:{{ countStore.upperSchool }}</h2>

八、$subscribe 状态监听(持久化必备)

作用监听 state 变化 ,只要 store 里的数据改变,就会触发回调函数
常用场景:状态持久化(存本地存储)

csharp 复制代码
// 获取情话store
const talkStore = useTalkStore()

// 订阅状态变化
talkStore.$subscribe((mutation, state) => {
  // mutation:变化的信息
  // state:最新的state数据
  console.log('状态变化了', mutation, state)
  // 本地存储持久化情话列表
  localStorage.setItem('talkList', JSON.stringify(state.loveTalk))
})

九、组合式写法(Setup 风格)

和 Vue3 组合式 API 写法一致,更灵活、更简洁,支持异步逻辑

csharp 复制代码
import { defineStore } from 'pinia'
import { reactive } from 'vue'
import axios from 'axios'
import { nanoid } from 'nanoid'

export const useTalkStore = defineStore('loveTalk', () => {
  // 1. 定义state(直接用reactive定义)
  const loveTalk = reactive(
    localStorage.getItem('talkList') 
      ? JSON.parse(localStorage.getItem('talkList')!) 
      : []
  )

  // 2. 定义action(方法)
  async function getLoveTalk() {
    // 异步请求情话接口
    const res = await axios.get('https://api.xygeng.cn/one')
    // 组装数据
    const obj = { id: nanoid(), title: res.data.data.content }
    // 更新state
    loveTalk.unshift(obj)
  }

  // 3. 必须return:暴露给组件使用的数据和方法
  return {
    loveTalk,
    getLoveTalk
  }
})

🎯 小结

  1. Pinia 是 Vue 官方新一代状态管理库,比 Vuex 简单
  2. 核心:state、getters、actions
  3. 修改数据:直接改 / $patch /action
  4. 解构用 storeToRefs
  5. 监听用 $subscribe
  6. 支持组合式 API写法,非常灵活
相关推荐
CHNE_TAO_EMSM40 分钟前
Android studio 打开文件时自动下载源码
前端·javascript·android studio
竹林8183 小时前
从 ethers.js 迁移到 Viem:一个签名验证 Bug 让我彻底放弃旧爱
javascript
你挚爱的强哥3 小时前
Vue2 实现 1.5s 十连击监听(连续点击若干次),封装通用可复用点击检测工具,不用 data!Vue 封装通用连击监听方法,支持自定义时长与点击次数
前端·javascript·vue.js
半个落月3 小时前
用 LangChain.js 手写一个能读写文件和执行命令的 Mini Cursor
javascript·人工智能·后端
天外天-亮4 小时前
HBuilder X 使用 uview-plus 方式
开发语言·javascript·hbuilder x·uview-plus
卓怡学长5 小时前
w266基于spring boot + vue 圣地延安美食乐享系统
java·数据库·vue.js·spring boot·spring·intellij-idea
我有满天星辰5 小时前
Vue项目脚手架之争:create-vue与Vue CLI全面对比
前端·javascript·vue.js
Random_index7 小时前
#Vue3篇: Vue 项目发版后如何提示用户刷新?基于 package.json 版本号的前端更新检测方案
前端·vue.js·json
多加点辣也没关系8 小时前
JavaScript|第9章:对象 — 基础
开发语言·javascript·ecmascript
我有满天星辰8 小时前
Vue 2 与 Vue 3 计算属性完全指南:从 Options API 到组合式 API 的演进
前端·javascript·vue.js