持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
pinia 简介
Pinia是一个全新的Vue状态管理库,由 Vue.js团队中成员所开发的,因此也被认为是下一代的 Vuex。同时是 vue 作者尤雨溪强势推荐的 vue3 状态管理工具.
pinia文档:pinia.vuejs.org/
Pinia 的优点
1、完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易。
2、极其轻巧(体积约 1KB)
3、store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法,这在 Vuex 中很常见。
4、支持多个Store,Pinia 不支持嵌套存储。相反,它允许你根据需要创建 store。但是,store 仍然可以通过在另一个 store 中导入和使用 store 来隐式嵌套。
5、支持 Vue devtools、SSR 和 webpack 代码拆分
- 更简单的写法,代码更清晰简洁,支持
composition api
和options api
语法 - 更完善的 typescript 支持,无需创建自定义复杂的包装类型来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断
- 非常轻量,只有1kb的大小
- 不需要再注入魔法字符串等进行调用
Pinia 的使用
安装
yarn add pinia
// or
pnpm add pinia
// or
npm install pinia
复制代码
创建并使用
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './app.vue'
createApp(App).use(createPinia()).mount('#app')
复制代码
定义 store
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
// state: () => {
// return { count: 0 }
// },
// could also be defined as
state: () => ({
count: 0
}),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
})
复制代码
使用
除了正常的使用方法外,注意下 storeToRefs
的使用.
<script setup>
// 引入 Pinia 及 store 文件
import {storeToRefs} from 'pinia'
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
// 如果直接从pinia中解构数据,会丢失响应式
// const { count, double } = counter
// 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
// 改变 count
const addPiniaCount = ()=>{
// counter.count++
// with autocompletion ✨
// counter.$patch({ count: counter.count + 1 })
// or using an action instead
counter.increment()
}
</script>
<template>
<div>
<p>
Pinia: count is: {{ counter.count }}, double:{{double}}
</p>
<button size="mini" @click="addPiniaCount">+</button>
</div>
</template>
复制代码
useMainStore实例化后的,我们就可以在 store 上访问 state、getters、actions 等
pinia中没有mutations。
订阅状态
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.$subscribe((mutation, state) => {
// mutation 触发类型 ( 'direct' | 'patch object' | 'patch function' )
console.log(mutation);
// state 就是 store 的状态
console.log(state);
})
</script>
复制代码
不推荐过度使用 数据状态管理工具
为什么不要过度用 Vuex 和 Pinia 呢?因为 Vuex 和 Pinia 处理的是全局变量,如果没有节制的使用则会造成高耦合,后期难以维护。