一.介绍
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:
Devtools 支持
追踪 actions、mutations 的时间线
在组件中展示它们所用到的 Store
让调试更容易的 Time travel
热更新
不必重载页面即可修改 Store
开发时可保持当前的 State
插件:可通过插件扩展 Pinia 功能
为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能。
支持服务端渲染
二.使用
import { createPinia } from 'pinia'
app.use(createPinia())
三.定义store
我们得知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:
你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)// 第一个参数是你的应用中 Store 的唯一 ID。
import { defineStore } from 'pinia'
export const useAlertsStore = defineStore('alerts', {
// 其他配置...
})
Option Store
与 Vue 的选项式 API 类似,我们也可以传入一个带有 state、actions 与 getters 属性的 Option 对象
import {defineStore} from 'pinia'
export const useCounterStore=defineStore("counter",{
state:()=>({count:5}),
getters:{
doubleCount:(state)=>state.count*2
},
actions:{
setCount(v){
this.count=v
}
}
})
Setup Store
import {defineStore} from 'pinia'
import {ref} from 'vue'
export const useUserStore = defineStore("user",()=>{
const userInfo = ref({})
const token = ref('')
function login(data){
}
function logout(){
}
return {userInfo,token,login,logout}
})
state
在大多数情况下,state 都是你的 store 的核心。人们通常会先定义能代表他们 APP 的 state。在 Pinia 中,state 被定义为一个返回初始状态的函数。
import { defineStore } from 'pinia'
const useStore = defineStore('storeId', {
// 为了完整类型推理,推荐使用箭头函数
state: () => {
return {
// 所有这些属性都将自动推断出它们的类型
count: 0,
name: 'Eduardo',
isAdmin: true,
items: [],
hasChanged: true,
}
},
})
访问state
const store = useStore()
store.count++
mapstate
<template>
<view>
大菠萝:{{doubleCount}}
<button @click="setCount(count+1)">{{count}}</button>
<button @click="counterStore.count++" type="primary">{{count}}</button>
</view>
</template>
<script>
import {useCounterStore} from '@/stores/useCounterStore.js'
import {mapState,mapActions,mapStores} from 'pinia';
export default{
data(){},
computed:{
...mapState(useCounterStore,["count","doubleCount"]),
...mapStores(useCounterStore)
},
methods:{
...mapActions(useCounterStore,["setCount"])
},
}
</script>
getter
Getter 完全等同于 store 的 state 的计算值。可以通过 defineStore() 中的 getters 属性来定义它们。推荐使用箭头函数,并且它将接收 state 作为第一个参数:
export const useStore = defineStore('main', {
state: () => ({
count: 0,
}),
getters: {
doubleCount: (state) => state.count * 2,
},
})
action
Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义,并且它们也是定义业务逻辑的完美选择。
export const useCounterStore = defineStore('main', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++
},
randomizeCounter() {
this.count = Math.round(100 * Math.random())
},
},
})