定义 Store | Pinia
开发文档
1.什么是Pinaia
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。
2.理解Pinaia核心概念
定义Store
在深入研究核心概念之前,我们得知道 Store 是用
defineStore()
定义的,它的第一个参数要求是一个独一无二的名字:import { defineStore } from 'pinia' // 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`) // 第一个参数是你的应用中 Store 的唯一 ID。 export const useAlertsStore = defineStore('alerts', { // 其他配置... })
这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use... 是一个符合组合式函数风格的约定。
defineStore()
的第二个参数可接受两类值:Setup 函数或 Option 对象。、在 Setup Store 中:
ref()
就是state
属性computed()
就是getters
function()
就是actions
使用Store
虽然我们前面定义了一个 store,但在我们使用
<script setup>
调用useStore()
(或者使用setup()
函数,像所有的组件那样) 之前,store 实例是不会被创建的<script setup> import { useCounterStore } from '@/stores/counter' // 可以在组件中的任意位置访问 `store` 变量 ✨ const store = useCounterStore() </script>
3.状态持久化
方法一 整体添加
main.ts入口文件添加整体持久化方案
import {createPinia} from 'pinia' const pinia = createPinia() if(localStorage.getItem("pinia")){ pinia.state.value = JSON.parse(localStorage.getItem("pinia")) } watch(pinia.state,state=>{ localStorage.setItem("pinia",JSON.stringify(state)) },{deep:true}) app.use(pinia)
方法二 插件
npm i pinia-plugin-persistedstate --save
import {createPinia} from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) app.use(pinia) import {ref, computed, watch} from 'vue' import {defineStore} from 'pinia' //counter是状态库id 或名称 export const useCounterStore = defineStore('counter', () => { //变量 state const count = ref(0) //计算属性 getter const doubleCount = computed(() => count.value * 2) //方法action function increment() { count.value++ } const user = ref({ name: '', desc: '一键三连' }) return {count, doubleCount, increment} }, {persist: true})
结果添加 ,{persist: true} 就可以持久化了
Pinanad的使用
components/Aa.vue 组件
components/Bb.vue组件
stores/counter.js 选项式的用法
stores/ token.js 组合式写法
main.js
import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) import { createPinia } from 'pinia' app.use(createPinia()) app.mount('#app')
App.vue
<script setup> import {version as v1, ref} from 'vue' import Bb from "@/components/Bb.vue"; import Aa from "@/components/Aa.vue"; const v2 = ref('2.1.6') import {useCounterStore} from './stores/counter' const c = useCounterStore() import {useTokenStore} from './stores/token' const us = useTokenStore() </script> <template> {{ v1 }} {{ v2 }} <h1>App</h1> <button @click="us.count++">add</button> <button @click="us.increment()">increment</button> <button @click="c.count++">add</button> <button @click="c.increment()">increment</button> <p>{{us.count}} ---{{us.doubleCount}}</p> <hr> <p>{{ c.count }} -- {{ c.doubleCount }}</p> <p>{{}}</p> <h1>Aa组件</h1> <Aa/> <h1>BB组件</h1> <Bb/> </template> <style scoped> </style>
count.js
import {computed, ref, watch} from 'vue' import {defineStore} from 'pinia' export const useCounterStore = defineStore('counter', () => { const count = ref(0) const doubleCount = computed(() => count.value * 2) function increment() { count.value++ } return {count, doubleCount, increment} })
token.js
import {defineStore} from 'pinia' export const useTokenStore = defineStore('token', { state: () => { return { count: 0, } }, getters: { doubleCount: state => state.count * 2 }, actions: { increment() { this.count++ } }, })
Aa.vue
<script setup> import {useCounterStore} from '../stores/counter.js' const cc = useCounterStore() import {useTokenStore} from '../stores/token' const us = useTokenStore() </script> <template> <h1>Aaaaaa</h1> <p>Aaa : {{ cc.count }} -- {{ cc.doubleCount }}</p> <button @click="cc.count+=5">Aa add +=5</button> <p>Aaa : {{ us.count }} -- {{ us.doubleCount }}</p> <button @click="us.count+=5">Aa add +=5</button> </template> <style scoped> </style>
Ba.vue
<script setup> import {useCounterStore} from '../stores/counter.js' const cc = useCounterStore() </script> <template> <h1>Bb</h1> <p>Bb : {{cc.count}} -- {{cc.doubleCount}}</p> </template> <style scoped> </style>