目录
一、pinia是干嘛的
二、安装Pinia
三、封装pinia
四、定义store
五、Store三个核心概念
1、第一个核心概念State
(1)使用state中的数据
(2)直接修改state中的数据
(3)$patch方法修改
(4)$state()方法替换state
(5)$reset() 方法重置state
2、第二个核心概念Getters
(1)定义getters
(2)页面中使用getters
3、第三个核心概念Action
(1)定义action
(2)使用action
三、pinia持久化存储
1、安装持久化插件pinia-plugin-persistedstate
(1)安装依赖
(2)将插件添加到 pinia 实例上
(3)用法
1.基本使用
2.高级使用
Pinia是 Vue 的存储库,它允许您跨组件/页面共享状态,与vuex功能一样。
yarn add pinia
# 或者使用 npm
npm install pinia
封装的作用:Pinia创建和pinia持久化插件引入都在这里做,(文章最后会介绍pinia持久化插件的使用),减少main.js代码的冗余
1、在src目录下创建stores文件夹,在文件夹下创建index.js文件。
2、index.js文件中写入
import { createPinia } from "pinia" //引入pinia
const pinia = createPinia() //创建pinia实例
export default pinia //导出pinia用于main.js注册
3、main.js中引入使用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './assets/reset.css'
import ElementPlus from 'element-plus'
import pinia from './stores' //引入
createApp(App).use(pinia).use(router).use(router).mount('#app') //使用
1、在stores文件夹下创建一个store ,名为user.js ,命名是尽量是见名知意的。
2、定义user.js
- Store 是使用
defineStore()
定义的,并且它需要一个唯一名称,作为第一个参数传递- 这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use... 是跨可组合项的约定
import { defineStore } from "pinia"
const useUserInfoStore = defineStore('userInfo', {
// defineStore('userInfo',{}) userInfo就是这个仓库的名称name
state: () => ({
username: '赫赫',
age: 30,
like: 'girl',
obj:{ money:100,friend:10 },
hobby: [
{ id: 1, name: '篮球', level: 1 },
{ id: 2, name: 'rap', level: 10 }
]
})
})
export default useUserInfoStore
State类似于组件中的data
- Store在它被使用之前是不会创建的,我们可以通过调用use函数来使用Store。
- 一旦 store 被实例化,你就可以直接在 store 上访问
state
、getters
和actions
中定义的任何属性store
是一个用reactive
包裹的对象,这意味着不需要在getter 之后写.value
,但是,就像setup
中的props
一样,我们不能对其进行解构
tips:不要使用结构赋值的方式取数据,会让数据失去响应式的特性。
我叫 {{ username }},我今年 {{ age }} 岁啦, 喜欢 {{ like }}
爱好有
{{ item.name }}
tips:修改相应的属性值
// 一个一个修改
const editPiniaHandler = () => {
userInfoStore.username += "嘎";
userInfoStore.age += 1;
userInfoStore.like = "boy";
};
tips:修改相应的属性值
//使用$patch方法 以对象的形式一次性修改
const editAll = () => {
userInfoStore.$patch({
username: "鸭蛋",
age: 21,
});
};
state
tips:替换相应的属性值
// $state 替换 state 为新对象
const replaceAll = ()=> {
userInfo.$state = {
name: '狗子',
age: '22',
like: 'boy',
obj:{ money:10, friend:1 }
}
}
tips:整个state的属性值都会变成定义时的初始值
// 重置state
const resetBtn = ()=> {
userInfoStore.$reset()
}
- Getters类似于组件中的计算属性
- Getters 只是幕后的 computed 属性,因此无法向它们传递任何参数。 但是,您可以从 getter 返回一个函数以接受任何参数
书接上文:getters定义与上文中的state同级书写
import { defineStore } from "pinia"
const useUserInfoStore = defineStore('userInfo', {
// defineStore('userInfo',{}) userInfo就是这个仓库的名称name
state: () => ({
username: '赫赫',
age: 30,
like: 'girl',
obj:{ money:100,friend:10 },
hobby: [
{ id: 1, name: '篮球', level: 1 },
{ id: 2, name: 'rap', level: 10 }
]
}),
getters: {
// 类似于计算属性,参数state指向defineStore下的state
doubleAge(state) {
return state.age * 2
},
//在getter中 使用另一个getter this指向当前存储库
addOneAge() {
return this.doubleAge + 1
},
//返回一个函数
returnFunction(state) {
return function (id) {
return state.hobby.find(item => item.id == id)
}
}
},
})
export default useUserInfoStore
乘2: {{ userInfoStore.doubleAge }}
加一: {{ userInfoStore.addOneAge }}
返回一个函数查找id为1的爱好: {{ userInfoStore.returnFunction(1) }}
Actions 相当于组件中的 methods。 它们可以使用
defineStore()
中的actions
属性定义,并且它们非常适合定义业务逻辑
tips:Actions支持异步操作的,可以编写异步函数
书接上文:action定义与上文中的state、getter同级书写,下面的代码不再赘述
//可以通过this访问整个store实例的所有操作,支持异步操作
actions: {
//非异步操作
addAge(e) {
console.log('接受的数据', e) //e是外部调用方法传递的参数
this.age = this.age + e
},
// 模拟异步
asynchronous() {
return new Promise((resolve)=> {
setTimeout(() => {
resolve('模拟异步返回值')
}, 2000);
})
},
// 异步操作
async getList () {
const res = await this.asynchronous()
console.log(res)
}
},
// 调用action中的方法
const add = ()=> {
userInfoStore.addAge(5)
}
//调用异步方法
const getLisst = ()=> {
userInfoStore.getList()
}
tips:官网连接
快速开始 | pinia-plugin-persistedstate (prazdevs.github.io)
npm i pinia-plugin-persistedstate
yarn add pinia-plugin-persistedstate
pnpm i pinia-plugin-persistedstate
tips:在上面封装的 index.js 文件基础上,引入插件并使用。
import { createPinia } from "pinia" //引入pinia
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //引入持久化插件
const pinia = createPinia() //创建pinia实例
pinia.use(piniaPluginPersistedstate) //将插件添加到 pinia 实例上
export default pinia //导出pinia用于main.js注册
书接上文:action定义与上文中的state、getter、action同级书写
创建 Store 时,将 persist
选项设置为 true,
整个 Store 将使用默认持久化配置保存。
默认持久化配置:
- 使用 localStorage进行存储
- store.$id作为 storage 默认的 key
- 使用 JSON.stringify / JSON.parse进行序列化/反序列化
- 整个 state 默认将被持久化
import { defineStore } from "pinia"
const useUserInfoStore = defineStore('userInfo', {
// defineStore('userInfo',{}) userInfo就是这个仓库的名称name
state: () => ({
username:'赫赫',
age: 23,
like: 'girl',
}),
getters: {
...........
},
action:{
.........
},
persist: true,
})
export default useUserInfoStore
如何你不想使用默认的配置,那么可以将一个对象传递给 Store 的
persist
属性来配置持久化
介绍三个常用属性:
key:存储名称。
storage:存储方式。
path:用于指定 state 中哪些数据需要被持久化。
[]
表示不持久化任何状态,undefined
或null
表示持久化整个 state。
import { defineStore } from "pinia"
const useUserInfoStore = defineStore('userInfo', {
// defineStore('userInfo',{}) userInfo就是这个仓库的名称name
state: () => ({
username:'赫赫',
age: 23,
like: 'girl',
obj:{ money:100,friend:10 }
}),
getters: {
...........
},
action:{
.........
},
persist: {
key: 'piniaStore', //存储名称
storage: sessionStorage, // 存储方式
paths: ['username', 'like','obj'], //指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state
},
})
export default useUserInfoStore
效果如图: