news 2026/5/1 11:38:26

Pinia 详细使用手册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pinia 详细使用手册

一、Pinia 核心概述

Pinia 是 Vue 官方推荐的新一代状态管理库,专为 Vue3 设计,也兼容 Vue2。它抛弃了 Vuex 的 Mutations,仅保留 State、Getters、Actions,API 极简、TypeScript 支持完善、轻量高效(约 1KB),是 Vue 项目状态管理的首选方案。

核心优势

  • 扁平化模块设计,无嵌套结构,维护更简单
  • 天然支持 TS,自动类型推导,编码更安全
  • 支持组合式(Setup)与选项式(Options)两种写法
  • 与 Vue DevTools 深度集成,支持时间旅行调试
  • 支持服务端渲染(SSR)与状态持久化

二、环境安装与初始化

1. 安装 Pinia

# npm npm install pinia # yarn yarn add pinia # pnpm(推荐) pnpm add pinia

2. 全局挂载(main.ts/main.js)

import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app=createApp(App) const pinia=createPinia() // 创建 Pinia 实例 app.use(pinia) // 挂载到 Vue 应用 app.mount('#app')

三、Store 定义(两种写法)

Store 是 Pinia 的核心,每个 Store 对应一个独立的状态模块,用defineStore定义,第一个参数为全局唯一 ID

1. 选项式写法(Options,类似 Vuex)

// stores/counter.ts import { defineStore } from 'pinia' export const useCounterStore=defineStore('counter', { // State:状态数据源,必须是函数(避免多实例污染) state: () => ({ count: 0, name: 'Pinia' }), // Getters:计算属性(缓存),类似组件 computed getters: { // 基础用法:接收 state doubleCount: (state) => state.count*2, // 访问其他 getter:用 this doubleCountPlusOne(): number { return this.doubleCount+1 } }, // Actions:同步/异步方法,类似组件 methods actions: { // 同步修改 increment() { this.count++ // 直接访问 state }, // 异步修改 async fetchData() { const res=await fetch('/api/data') const data=await res.json() this.name=data.name } } })

2. 组合式写法(Setup,Vue3 风格)

更灵活,支持 Vue 组合式 API(ref/reactive/computed):

// stores/user.ts import { defineStore } from 'pinia' import { ref, computed } from 'vue' export const useUserStore=defineStore('user', () => { // State:用 ref/reactive 定义 const username=ref('游客') const token=ref('') const isLogin=ref(false) // Getters:用 computed 定义 const upperUsername=computed(() => username.value.toUpperCase()) // Actions:用普通函数定义 function login(data: { username: string; token: string }) { username.value=data.username token.value=data.token isLogin.value=true } function logout() { username.value='游客' token.value='' isLogin.value=false } // 返回 state/getters/actions(暴露给组件) return { username, token, isLogin, upperUsername, login, logout } })

四、组件中使用 Store

1. 基础用法(直接访问)

<template> <div> <p>计数:{{ counter.count }}</p> <p>双倍计数:{{ counter.doubleCount }}</p> <button @click="counter.increment">+1</button> </div> </template> <script setup> // 导入 store import { useCounterStore } from '@/stores/counter' // 创建 store 实例 const counter=useCounterStore() </script> ```{insert\_element\_0\_} ### 2. 解构用法(保持响应式) 用 `storeToRefs` 解构,避免直接解构丢失响应式: ```vue <template> <div> <p>用户名:{{ username }}</p> <p>大写用户名:{{ upperUsername }}</p> <button @click="handleLogin">登录</button> </div> </template> <script setup> import { useUserStore } from '@/stores/user' import { storeToRefs } from 'pinia' const userStore=useUserStore() // 解构:state/getters 用 storeToRefs,actions 直接解构 const { username, upperUsername }=storeToRefs(userStore) const { login }=userStore function handleLogin() { login({ username: '张三', token: '123456' }) } </script>

五、State 操作详解

1. 直接修改

const counter=useCounterStore() counter.count=10 // 直接赋值修改

2. 批量修改($patch)

一次性修改多个状态,性能更优:

// 对象形式 counter.$patch({ count: 5, name: 'New Pinia' }) // 函数形式(更灵活,支持逻辑) counter.$patch((state) => { state.count += 3 state.name += ' Pro' }) ```{insert\_element\_1\_} ### 3. 重置状态($reset) 恢复 state 到初始值: ```javascript counter.$reset() // { count: 0, name: 'Pinia' }

4. 替换整个状态($state)

直接覆盖 state:

counter.$state={ count: 100, name: 'Replace Pinia' }

六、Getters 高级用法

1. 依赖其他 Getters

getters: { doubleCount: (state) => state.count*2, // 依赖 doubleCount quadrupleCount(): number { return this.doubleCount*2 } }

2. 传参 Getters

返回函数实现传参:

getters: { getCountByN: (state) => { return (n: number) => state.count*n } } // 组件中使用:counter.getCountByN(3)

3. 访问其他 Store 的 Getters

import { useUserStore } from './user' getters: { userInfo(): string { const userStore=useUserStore() return userStore.username } }

七、Actions 高级用法

1. 异步操作

actions: { async getUserInfo(userId: number) { const res=await fetch(`/api/user/${userId}`) const data=await res.json() this.userInfo=data // 修改 state return data // 返回结果给组件 } } // 组件中调用:await userStore.getUserInfo(1)

2. 访问其他 Store 的 Actions

import { useCounterStore } from './counter' actions: { incrementAndLog() { const counterStore=useCounterStore() counterStore.increment() // 调用其他 store 的 action console.log('计数已增加') } }

3. 批量修改状态

Actions 中可直接修改多个 state,无需$patch

actions: { updateUser() { this.username='李四' this.token='654321' this.isLogin=true } }

八、状态持久化(pinia-plugin-persistedstate)

默认状态刷新页面会丢失,用持久化插件保存到 localStorage/sessionStorage。

1. 安装插件

npm install pinia-plugin-persistedstate # yarn add pinia-plugin-persistedstate # pnpm add pinia-plugin-persistedstate

2. 全局注册(main.ts)

import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia=createPinia() pinia.use(piniaPluginPersistedstate) // 注册持久化插件

3. 启用持久化(Store 中)

选项式:
export const useUserStore=defineStore('user', { state: () => ({ username: '游客', token: '' }), persist: true // 开启当前 store 持久化 })
组合式:
export const useUserStore=defineStore('user', () => { const username=ref('游客') return { username } }, { persist: true // 开启持久化 })

4. 自定义持久化规则

persist: { key: 'user-info', // 自定义存储 key storage: sessionStorage, // 存储位置(默认 localStorage) paths: ['username'], // 仅持久化指定字段 // 加密存储(敏感数据) serialize: (state) => { return JSON.stringify({ ...state, token: btoa(state.token) }) }, deserialize: (value) => { const state=JSON.parse(value) state.token=atob(state.token) return state } }

九、模块化与多 Store

1. 目录结构(推荐)

src/ ├── stores/ │ ├── index.ts # 统一导出 │ ├── counter.ts │ ├── user.ts │ └── cart.ts

2. 统一导出(stores/index.ts)

export { useCounterStore } from './counter' export { useUserStore } from './user' export { useCartStore } from './cart'

3. 组件中导入

import { useCounterStore, useUserStore } from '@/stores'

十、TypeScript 支持

Pinia 天然支持 TS,自动类型推导:

// 选项式:自动推导 state/getters/actions 类型 export const useCounterStore=defineStore('counter', { state: () => ({ count: 0 }), actions: { increment() { this.count++ // TS 自动识别 count 类型 } } }) // 组合式:ref/computed 自动推导类型 const count=ref(0) // 类型:Ref<number>

十一、常见问题与避坑

  1. 解构后丢失响应式:必须用storeToRefs解构 state/getters,actions 可直接解构。
  2. State 必须是函数:避免多个组件实例共享同一状态,导致数据污染。
  3. 持久化异步数据:确保异步操作完成后再修改 state,否则插件无法监听。
  4. 全局 ID 唯一:defineStore 的第一个参数必须全局唯一,否则状态冲突。

十二、官方文档与资源

  • 官方文档:https://pinia.vuejs.org/zh/
  • GitHub 仓库:https://github.com/vuejs/pinia
  • 持久化插件:https://github.com/prazdevs/pinia-plugin-persistedstate
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 11:33:24

对话式AI反馈系统设计:提升用户体验的四维实践

1. 对话式AI的反馈困境本质剖析 当用户面对一个回答"我明白了"的AI助手时&#xff0c;超过62%的受访者表示会直接放弃纠正错误回答&#xff08;2023年Conversational AI Research数据&#xff09;。这种反馈断裂现象背后隐藏着三个设计盲区&#xff1a; 第一是认知负…

作者头像 李华
网站建设 2026/5/1 11:30:18

如何快速解密网易云音乐NCM格式:3种简单方法重获音乐自由

如何快速解密网易云音乐NCM格式&#xff1a;3种简单方法重获音乐自由 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾为网易云音乐下载的NCM格式歌曲无法在其他设备播放而烦恼&#xff1f;那些精心收藏的音乐文件就像被锁在…

作者头像 李华
网站建设 2026/5/1 11:27:23

5分钟搞定视频字幕提取:本地化多语言字幕提取工具完整指南

5分钟搞定视频字幕提取&#xff1a;本地化多语言字幕提取工具完整指南 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包含字幕区域检测、字幕…

作者头像 李华