什么是Pinia?

Pinia是一个轻量级的状态管理库,用来管理全局状态的工具。

Pinia | The intuitive store for Vue.js (vuejs.org)

它能够解决如下问题:

  1. 全局状态管理:所有组件都可以访问和修改状态,不用在每个组件的内部进行管理
  2. 简化组件之间的通信:避免使用大量的prop和provide
  3. 状态持久化:可以将数据储存在本地存储中,在应用重启后仍然会保留状态,本质是将数据存储在LocalStorage中。

常见的应用在保持用户的登录状态。

Pinia和LocalStorage有一些区别:

  • LocalStorage只允许存储字符串类型,大小限制为5MB(适合简单场景)
  • Pinia可以存储任何的数据类型,没有数据大小的限制(适合复杂场景)

安装Pinia

在终端输入:

1
npm install pinia

之后在package.json文件中就可以找到pinia的版本信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"name": "demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"pinia": "^2.1.7",
"vue": "^3.4.21"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"vite": "^5.2.0"
}
}

安装之后就可以在main.js中创建一个pinia实例:

1
2
3
4
5
6
7
8
9
10
11
import { createApp } from 'vue'
import App from './App.vue'

import { createPinia } from 'pinia'

const pinia = createPinia()

const app = createApp(App)

app.use(pinia)
app.mount('#app')

之后我们在src目录下创建一个stores的文件夹,创建一个web.js文件,在文件中创建一个store对象.

defineStore有两个参数:id(最好和js文件名相同)和setup函数(或者是Option对象)

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { defineStore } from "pinia";
import { reactive,ref } from "vue";

defineStore("web",()=>{
const web = reactive({
title:"百度",
url:"https://www.baidu.com"
})

const users = ref(1000)

const userAdd = ()=>{
users.value++
}

return {
web,
users,
userAdd
}
})

定义后使用export导出,变量的命名是由use+Id+Store组成:

1
export const useWebStore = defineStore("web",……)

导出后就可以在组件中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
import { useWebStore } from './stores/web';

const useWeb = useWebStore();

console.log(useWeb.web.title)
console.log(useWeb.users)

</script>

<template>
{{ useWeb.web.title }}
{{ useWeb.users }}

<button @click="useWeb.userAdd">添加用户</button>

</template>

<style scoped>

</style>

可以看出pinia就是将状态组件进行了集中的管理。

持久化存储

为了关闭浏览器的时候用户的状态不发生丢失,需要使用localStorage将数据保存下来。

这里需要使用到一个本地持久化存储插件:pinia-plugin-persistedstate

Home | pinia-plugin-persistedstate (prazdevs.github.io)

首先要安装插件:

1
npm i pinia-plugin-persistedstate

安装后在package.json中可以可看到对应的版本信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"name": "demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"vue": "^3.4.21"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"vite": "^5.2.0"
}
}

之后在main.js中创建一个实例,并作用于pinia:

1
2
3
4
5
6
7
8
9
10
11
12
13
import { createApp } from 'vue'
import App from './App.vue'

import { createPinia } from 'pinia'
import { createPersistedState } from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(createPersistedState())

const app = createApp(App)

app.use(pinia)
app.mount('#app')

web.jsdefineStore的末尾添加一个参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { defineStore } from "pinia";
import { reactive,ref } from "vue";

export const useWebStore = defineStore("web",()=>{
const web = reactive({
title:"百度",
url:"https://www.baidu.com"
})

const users = ref(1000)

const userAdd = ()=>{
users.value++
}

return {
web,
users,
userAdd
}
},
{
persist:true
})

这样就开启了持久化存储,在浏览器调试工具的应用程序中的本地存储即可看到数据的内容,且刷新后内容不丢失。