安装插件
- npm install pinia
- npm install pinia-plugin-persistedstate
文件配置
方法一
- 在store/index.js文件中进行初始化配置
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
export function setupStore(app) {
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) //使用持久化存储插件
app.use(pinia)
}
export * from './modules/user'
- 在main.js入口文件中引入pinia配置
import {
createSSRApp
} from "vue";
import App from "./App.vue";
/** pinia */
import { setupStore } from './store/index.js'
export function createApp() {
const app = createSSRApp(App);
setupStore(app); //pinia
return {
app,
};
}
方法二
- 直接在main.js文件中进行配置
import { createApp } from 'vue'
import App from './App.vue'
// pinia
import { createPinia } from 'pinia'
// pinia中数据持久化
import { persistedState } from 'pinia-plugin-persistedstate'
// pinia配置
const pinia=createPinia()
pinia.use(persistedState)
createApp(App)
.use(pinia)
.mount('#app')
创建pinia模块
- store/modules/user.js
//user.js
import { defineStore } from "pinia";
/**
* 参数1:命名空间名称 唯一id
* 参数2: {
state
getters
actions
persist
}
*/
// useUserStore: 推荐使用 use + id + Store 来命名
export const useUserStore = defineStore("User", {
state: () => ({
userName: "",
age:18,
obj:{ money:9999,house:99 },
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);
};
},
},
//可以通过this访问整个store实例的所有操作,支持异步操作
actions: {
//非异步操作
addAge(e) {
console.log("接受的数据", e); //e是外部调用方法传递的参数
//方法一
this.age = this.age + e;
//方法二
// this.$patch((state) => {
// state.age += e;
// });
},
// 模拟异步
asynchronous() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("模拟异步返回值");
}, 2000);
});
},
// 异步操作
async getList() {
const res = await this.asynchronous();
console.log(res);
},
},
persist:true,
});
页面中使用
state
- State类似于组件中的data
- Store在它被使用之前是不会创建的,我们可以通过调用use函数来使用Store。
- 一旦 store 被实例化,你就可以直接在 store 上访问 state、getters 和 actions 中定义的任何属性
- store 是一个用reactive 包裹的对象,这意味着不需要在getter 之后写.value,但是,就像setup 中的props 一样,我们不能对其进行解构
<template>
<div class="content">
<div>我叫{{ userName }},今年{{ age }}岁</div>
<div>财富有{{ obj.money }}万元</div>
<div>其他资产有{{ obj.house || obj.friend }}个</div>
<div>爱好有</div>
<div v-for="item in hobby" :key="item.id">
<div>{{ item.name }}</div>
</div>
<button @click="editPiniaHandler">点击修改</button>
<button @click="editAll">点击修改全部</button>
<button @click="replaceAll">替换</button>
<button @click="resetBtn">重置</button>
</div>
</template>
<script setup>
// import { ref } from 'vue';
import { useUserStore } from '@/store/index.js' //引入仓库
import { storeToRefs } from "pinia"; //引入pinia转换
const userInfoStore = useUserStore()
// const { username, age, like, hobby } = userInfoStore //直接结构赋值 不是响应式
const { userName, age, hobby, obj } = storeToRefs(userInfoStore); // 响应式
// 一个一个修改
const editPiniaHandler = () => {
userInfoStore.userName = "小明";
userInfoStore.age += 1;
};
//使用$patch方法 以对象的形式一次性修改
const editAll = () => {
userInfoStore.$patch({
userName: "鸭蛋",
age: 21,
});
};
// $state 替换 state 为新对象
const replaceAll = () => {
userInfoStore.$state = {
userName: '狗子',
age: '22',
obj: { money: 10, friend: 1 },
hobby: [
{ id: 1, name: "足球", level: 1 },
{ id: 2, name: "唱歌", level: 10 },
],
}
}
// 重置state
const resetBtn = () => {
userInfoStore.$reset()
}
</script>
<style lang="scss" scoped>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
getters
- Getters类似于组件中的计算属性
- Getters 只是幕后的 computed 属性,因此无法向它们传递任何参数。 但是,您可以从 getter 返回一个函数以接受任何参数
<!-- getter的使用 -->
<div>乘2: {{ userInfoStore.doubleAge }}</div>
<div>加一: {{ userInfoStore.addOneAge }}</div>
<div>返回一个函数查找id为1的爱好: {{ userInfoStore.returnFunction(1) }}</div>
actions
- Actions 相当于组件中的 methods。它们可以使用
defineStore()
中的actions
属性定义,并且它们非常适合定义业务逻辑- Actions支持异步操作的,可以编写异步函数
<!-- action的使用 -->
<button @click="add">非异步</button>
<button @click="getList">异步</button>
// 调用action中的方法
const add = () => {
userInfoStore.addAge(5)
}
//调用异步方法
const getList = () => {
userInfoStore.getList()
}
模块的持久化配置
pinia持久化文档官网 prazdevs.github.io/pinia-plugi…
/** 持久化使用方法1
* 当前模块所有数据都进行持久化
* 使用localStorage进行存储
* 默认将id作为storage中的key
* 使用JSON.stringify / JSON.parse进行序列化/反序列化
*/
persist: true,
/** 持久化使用方法2
* key:存储名称
* storage:存储方式
* path:用于指定state中哪些数据需要被持久化,[]表示不持久化任何状态,undefined或null表示持久化整个state
*/
persist: {
key: 'piniaStore', //存储名称
storage: sessionStorage, // 存储方式
paths: ['userName','obj'], //指定存储的数据
},
/** 持久化使用方法3*/
`userName` 值将保存在 `localStorage` 中,
`obj` 值将保存在 `sessionStorage` 中。
`age` 没有被持久化
persist:[
{
pick:["userName"],
storage:localStorage
},
{
pick:["obj"],
storage:sessionStorage
}
],
在uniapp中使用持久化插件
// store/index.js
import { createPinia } from "pinia";
import { createPersistedState } from "pinia-plugin-persistedstate";
export function setupStore(app) {
const pinia = createPinia();
pinia.use(createPersistUni()); //使用持久化存储插件
app.use(pinia);
}
/**
* @description 自定义pinia持久化API存储方式为uni
*/
// 应用于所有模块,如在特定模块设置则写到对应模块
function createPersistUni() {
return createPersistedState({
storage: {
getItem: uni.getStorageSync,
setItem: uni.setStorageSync,
},
});
}
export * from "./modules/user";
// store/moddules/user.js
......
persist: true, // 是否开启持久化(当前模块所有数据都进行持久化)
// 配置持久化
persist: {
pick: ["userName"],
},
// 配置此模块的持久化存储方式
persist: {
storage: { // 修改存储方式
getItem: uni.getStorageSync,
setItem: uni.setStorageSync
},
key: 'userInfo', // 本地存储key值
pick: ['obj.money', 'age'] // 指定持久化的数据,不写默认持久化整个state
}