Pinia入门
什么是pinia
Pinia 是 Vue 的专属状态管理库,可以实现跨组件或页面共享状态,是 vuex 状态管理工具的替代品,和 Vuex相比,具备以下优势
- 提供更加简单的API (去掉了 mutation )
- 提供符合组合式API风格的API (和 Vue3 新语法统一)
- 去掉了modules的概念,每一个store都是一个独立的模块
- 搭配 TypeScript 一起使用提供可靠的类型推断
通俗理解: 我们可以认为Pinia 是一个共享储物柜,专门帮你解决Vue项目中组件之间 数据相互拿不到或数据不同步的烦恼
举个栗子🌰:
- 场景: 你做了一个电商网站,用户头像和昵称(比如“小明”)需要在导航栏、个人主页、侧边栏等多个地方显示。如果用传统方法,每个组件都要单独传值,麻烦得要死!
- 用 Pinia 后:
- 建一个叫
userStore的储物柜,把用户数据(小明的信息)存进去。 - 导航栏、个人主页、侧边栏这些组件 直接去储物柜里拿数据,不用层层传递。
- 如果小明修改了昵称,储物柜里的数据自动更新,所有用到的地方立刻同步!
- 建一个叫
通俗总结它的用处:
- 共享数据:像购物车、用户信息这类多个页面都要用的数据,不用再靠组件之间“互相传纸条”。
- 自动同步:数据一变,所有用到的地方自动更新(比如购物车数量实时变化)。
- 代码清爽:把零散在各处的数据集中放到“储物柜”,好维护、好找bug。
再举个生活化例子:
想象全家共用一台智能冰箱(Pinia):
- 妈妈买了苹果(修改数据),所有人打开冰箱都能看到(自动同步)。
- 不用挨个打电话通知:“冰箱有苹果啦!”(省掉 props 传值)。
- 爸爸想吃香蕉,直接往冰箱里加(任何组件都能改数据)。
这就是 Pinia 的作用——让数据共享变简单,告别繁琐传值! 🚀
创建空Vue项目并安装Pinia
1. 创建空Vue项目
1 | npm init vue@latest |
2. 安装Pinia并注册
1 | npm i pinia |
1 |
|
实现counter
核心步骤: 官方文档 stores目录下新建一个counter.js
- 定义store
- 组件使用store
1- 定义store1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCounterStore = defineStore('counter', ()=>{
// 定义数据 (state)
const count = ref(0)
// 定义修改数据的方法 (action 同步+异步)
const increment = ()=>{
count.value++
}
// 以对象形式返回供组件使用
return {
count,
increment
}
})
2- 组件使用store
App.vue
1 | <script setup> |
实现getters
getters直接使用计算属性computed函数进行模拟即可实现
1 | // 数据(state) |
异步action
思想:action函数既支持同步也支持异步,和在组件中发送网络请求写法保持一致
步骤:
- store中定义action
- 组件中触发action
1- store中定义action1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const API_URL = 'http://geek.itheima.net/v1_0/channels'
export const useCounterStore = defineStore('counter', ()=>{
// 数据
const list = ref([])
// 异步action
const loadList = async ()=>{
const res = await axios.get(API_URL)
list.value = res.data.data.channels
}
return {
list,
loadList
}
})
2- 组件中调用action1
2
3
4
5
6
7
8
9
10
11
12<script setup>
import { useCounterStore } from '@/stores/counter'
const counterStore = useCounterStore()
// 调用异步action
counterStore.loadList()
</script>
<template>
<ul>
<li v-for="item in counterStore.list" :key="item.id">{{ item.name }}</li>
</ul>
</template>
storeToRefs保持响应式解构
直接基于store进行解构赋值,响应式数据(state和getter)会丢失响应式特性,使用storeToRefs辅助保持响应式
1 | <script setup> |




