介绍
Pinia是Vue的专属状态管理库,它允许我们跨组件或页面共享状态,官方文档链接:Home | Pinia (vuejs.org)
安装
我使用的Vue.js版本是3.2.45(也就是Vue3),并且项目使用Vite4创建的,Vue3安装Pinia只需要执行下面的命令即可,Vue2则还需要安装一个插件,这里不讨论,可以去查看官方文档:安装 | Pinia (vuejs.org)
使用
创建实例传递给应用
创建一个pinia实例(根store)并将其传递给应用
1 2 3 4 5 6 7 8
| import { createApp } from 'vue' import { createPinia } from "pinia" import './style.css' import App from './App.vue'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
|
定义store
在/src/stores
目录下创建一个index.ts
文件
useStore
是返回值的名称,main
是名字id,都可以随意命名,但是返回值的名称最好使用store的名字,同时以 use
开头且以 Store
结尾(比如 useUserStore
,useCartStore
,useProductStore
)
1 2 3 4 5
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { })
|
State
定义state
state是store的核心,用于跨组件或页面共享状态
1 2 3 4 5 6 7 8 9
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { state: () => { return { count: 1 } } })
|
访问state
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <script setup lang="ts">
import { useStore } from "./stores/index";
const store = useStore();
const addCount = () => { store.count++; }; </script>
<template> <div> <h1>{{ store.count }}</h1> <button @click="addCount">+1</button> </div> </template>
<style scoped> div { text-align: center; } h1 { color: red; } </style>
|
重置state
通过store.$reset()
可以重置state的值
1 2 3 4
| const reset = () => { store.$reset(); };
|
变更state
通过store.$patch
修改state(一般用于修改多个数据),只修改一个可以直接修改
1 2 3 4 5 6 7 8 9 10
| const modify = (): void => { store.$patch(state => { state.count = 123 }) };
const modify2 = (): void => { store.count = 123; };
|
替换state
替换和变更的区别就是,替换用于修改全部数据,而变更是修改一个或多个数据
1 2 3 4 5 6 7
| const replace = (): void => { store.$state = { count: 666, name: "jack", }; };
|
订阅state
通过store.$subscribe
方法订阅state后,一旦state的数据发生变更,我们可以对变更后的数据进行一些操作,例如可以对数据进行持久化,不然一刷新页面数据就重置了
mutation返回值包含了操作的状态、state改变前的值、state改变后的值……
state返回值则是修改后的state的数据
上面两个返回值的名称可以随便写
1 2 3 4 5 6
| store.$subscribe((mutation, state) => { console.log(mutation); console.log(state); window.localStorage.setItem("useStoreState", JSON.stringify(state)); });
|
Getter
Getter完全等同于store的state的计算值,接收 state
作为第一个参数,对state的数据进行统一处理,下面的doubleCount
是对state.count乘以2
,直接通过store.doubleCount()
调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { state: () => { return { count: 1, name: 'tom' } }, getters: { doubleCount: (state) => state.count * 2 } })
|
调用同一个store的getter可以使用this
关键词
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { state: () => { return { count: 1, name: 'tom' } }, getters: { doubleCount: (state) => state.count * 2, doublePlusOne(): number { return this.doubleCount + 1 } } })
|
Action
Action相当于组件中的method,在组件中直接通过store.increment()
进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { state: () => { return { count: 1, name: 'tom' } }, getters: { doubleCount: (state) => state.count * 2, doublePlusOne(): number { return this.doubleCount + 1 } }, actions: { increment() { this.count++ } } })
|
持久化
介绍
state改变后,一旦刷新页面后就恢复默认值了,如果我们需要保留修改后的state,那么就需要将state持久化了,持久化的方法有两个:
- 使用
pinia-plugin-persist
插件,建议使用
- 通过订阅state将每次改变后的数据通过
localStorage
或者sessionStorage
持久化到本地
使用插件
安装
使用下面命令安装
1
| npm i pinia-plugin-persistedstate
|
引入
在main.ts
中全局引入
1 2 3 4 5 6 7 8 9 10
| import { createApp } from 'vue' import { createPinia } from "pinia" import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import './style.css' import App from './App.vue'
const pinia = createPinia() pinia.use(piniaPluginPersistedstate)
createApp(App).use(pinia).mount('#app')
|
使用
在要持久化的store中加上persist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { defineStore } from "pinia"
export const useStore = defineStore('main', { state: () => { return { count: 1, name: 'mary' } }, persist: { key: 'useStore', storage: sessionStorage, paths: ['count', 'name'] } })
|
参数说明如下:
参数 |
说明 |
key |
自定义存储的key,默认是store.$id |
storage |
存储的类型:sessionStorage 或localStorage ,默认是sessionStorage |
paths |
要持久化的数据,state中的字段名,默认是全部 |
通过订阅state
首先订阅state,然后将数据放到localStorage
或sessionStorage
中
1 2 3 4 5 6
| store.$subscribe((mutation, state) => { console.log(mutation); console.log(state); window.localStorage.setItem("useStoreState", JSON.stringify(state)); });
|
需要持久化哪个数据就从本地存储的state中获取它,不然就是默认值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { defineStore } from "pinia"
const json: string = window.localStorage.getItem("useStoreState") || '{"count":1,"name":"tom"}'
const obj: any = JSON.parse(json)
export const useStore = defineStore('main', { state: () => { return { count: obj.count, name: obj.name } }, getters: { doubleCount: (state) => state.count * 2, doublePlusOne(): number { return this.doubleCount + 1 } }, actions: { increment() { this.count++ } } })
|