它是2019 年 11 月对于新版本的vue提供的组合Api进行的尝试,它可以很好的集合vue新的api方法,且还很好的支持ts的写法,Pinia已经被纳入官方代码仓库中,也可以理解为Pinia为最新版本的vuex5。

Vuex 当前最新版是 4.x
Pinia 当前最新版是 2.x,它即支持 Vue2 也支持 Vue3。就目前而言 Pinia 是我们在vue3 项目中的首选,尤其是 TypeScript 的项目。
安装:
yarn add pinia
使用:
在入口文件进行初始化(main.js):
// 创建vue入口程序,由原来的类实例,变成现在的函数方式,为了更好在打包时优化代码
import { createApp } from 'vue'
// 根组件
import App from './App.vue'
// 路由
import router from './router'
import createGlobalComponent from './components'
import globalProperties from './config/globalProperties'
// pinia
import { createPinia } from 'pinia'
// pinia配置
const pinia=createPinia()
// 工作中常用写法:
createApp(App)
.use(createGlobalComponent)
.use(globalProperties)
.use(router)
.use(pinia)
.mount('#app')
创建 pinia 模块(pinia/film.js):
import { defineStore } from 'pinia'
// 参数1:命名空间名称
// 参数2:对象,配置 state getters actions
const useFilmStore = defineStore('film',{
state:()=>({
num:100
}),
actions:{
}
})
export default useFilmStore
电影页面:
<template>
<div>
<h3>电影列表 -- {{ store.num }} -- {{num}}h3>
<button @click="addNum">++++button>
div>
template>
<script setup>
import { storeToRefs } from 'pinia';
// 状态是完全独立的一个模块
import useFilmStore from '../pinia/film';
const store = useFilmStore()
// 使用 storeToRefs 可以解构出来 state 中的属性,而且它还保持响应式
const { num } = storeToRefs(store)
// pinia不用通过commit方法更改数据,可以直接在组件中更改数据,并且是响应式的
const addNum = () => {
store.num++
}
script>
<style lang="scss" scoped>
style>
电影页面:
<template>
<div>
<h3>电影列表 -- {{ store.num }} -- {{ num }}h3>
<ul>
<li v-for="item of store.arr" :key="item">{{ item }}li>
ul>
<button @click="addNum">++++button>
div>
template>
<script setup>
import { storeToRefs } from 'pinia';
// 状态是完全独立的一个模块
import useFilmStore from '../pinia/film';
const store = useFilmStore()
// 使用 storeToRefs 可以解构出来 state 中的属性,而且它还保持响应式
const { num } = storeToRefs(store)
// pinia不用通过commit方法更改数据,可以直接在组件中更改数据,并且是响应式的
const addNum = () => {
// 方案一:直接修改 state 中的数据,这种方式无法进行批处理,如果修改的属性过多,性能不高
// store.num++
// 方案2:批处理,如果一次性修改多个属性建议用$patch来完成,性能更高
// store.$patch({
// num: store.num + 1,
// arr: store.arr.concat(Date.now())
// })
// 方案2回调函数写法:批处理,回调函数写法来批量修改,这样可以防止$patch如果进行了对象合并,批处理数据不完整的情况出现
// store.$patch(state => {
// store.num + 1
// store.arr.push(Date.now())
// })
// 方案3:调用pinia模块下的actions中的方法,完成数据更新
store.addNum(1)
}
script>
<style lang="scss" scoped>
style>
pinia/film.js:
import { defineStore } from 'pinia'
// 参数1:命名空间名称
// 参数2:对象,配置 state getters actions
const useFilmStore = defineStore('film', {
state: () => ({
num: 100,
arr: [1, 2, 3]
}),
actions: {
addNum(n) {
// 方案1
// 同步
this.num += n
// 异步
setTimeout(() => {
this.num += n
}, 1000)
// 方案2
this.$patch(state=>{
state.num+=n
state.arr.push(Date.now())
})
},
}
})
export default useFilmStore

安装:
yarn add pinia-plugin-persistedstate@2
入口文件中导入:
// pinia中数据持久化
import { persistedState } from 'pinia-plugin-persistedstate'
pinia.use(persistedState)
在pinia模块中使用:
import { defineStore } from 'pinia'
// 参数1:命名空间名称
// 参数2:对象,配置 state getters actions
const useFilmStore = defineStore('film', {
// 当前pinia模块中的所有的数据进行持久化处理
// 默认使用的是 localStorage,且它存储在 localStorage 中的 key 的名称为命名空间名称[id名称]
// persist: true,
// 指定模块中要持久化的数据
persist: {
// 指定要持久化的 state 对象中的属性名称
paths: ['num'],
// 自定义localStorage中的key的名称,一般不修改
key: 'filmstore',
// 自定义使用localStorage还是sessionStorage存储介质
storage: window.sessionStorage
},
state: () => ({
num: 100,
arr: [1, 2, 3]
}),
actions: {
addNum(n) {
// 方案1
// 同步
this.num += n
// 异步
setTimeout(() => {
this.num += n
}, 1000)
// 方案2
this.$patch(state => {
state.num += n
state.arr.push(Date.now())
})
},
}
})
export default useFilmStore

Pinia中文文档:https://pinia.web3doc.top/core-concepts/plugins.html