vue3 + ts + pinia 网页端 和 移动端集中式状态管理
一、Pinia 介绍:
- 官网
- Pinia 是 Vue 的存储库,可以跨组件/页面全局共享,数据是存储在缓存中。
优点:
1、pinia 符合直觉,易于学习。
2、pinia 是轻量级状态管理工具,大小只有1KB。
3、pinia 模块化设计,方便拆分。
4、pinia 没有 mutations ,直接在 actions 中操作 state ,通过 this.xxx 访问响应的状态,尽管可以直接操作 state ,但是还是推荐在 actions 中操作,保证状态不被以外的改变。
5、store 的 actions 被调度为常规的函数调用,而不是使用 dispatch 方法或者是 MapAction 辅助函数,这是在 Vuex 中很常见的。
6、支持多个 store 。
7、支持 Vuex devtools(调试工具)、SSR、webpack 代码拆分。
二、移动端
uni-app
为例
1、安装 pinia 和 pinia-plugin-persistedstate
npm install pinia@2.0.30 --legacy-peer-deps
npm install pinia-plugin-persistedstate
2、创建 store
- 在 src 目录中创建 stores文件夹,并创建 index.ts文件,文件实例代码如下:
import { createPinia } from "pinia";
import persist from "pinia-plugin-persistedstate"; // 持续化插件
// 创建 Pinia 实例
const pinia = createPinia();
// 使用 持久化 插件
pinia.use(persist);
// 导出 pinia
export default pinia;
// 模块统一导出(业务 store)
export * from "./modules/user";
3、在 main.ts 中挂载 pinia,示例代码如下:
import { createSSRApp } from "vue";
import App from "./App.vue";
// 导入 pinia 实例
import pinia from "./store/index";
export function createApp() {
// 创建 vue 实例
const app = createSSRApp(App);
// 使用 pinia
app.use(pinia);
return {
app,
};
}
4、创建业务 Store,示例代码如下:
- 文件夹 Store 中创建 modules 文件夹,再文件夹中创建 user.ts 文件,文件代码如下:
import { defineStore } from "pinia";
import { ref } from "vue";
// 创建 store
export const userName = defineStore(
"user",
() => {
// 定义默认用户名称
const name = ref("欢迎使用 uni-app");
// 修改用户名称方法
const setUserName = (val: any) => {
name.value = val;
};
// 返回
return {
name,
setUserName,
};
},
{
// 移动端持久化配置
persist: {
storage: {
getItem(key) {
return uni.getStorageSync(key);
},
setItem(key, value) {
uni.setStorageSync(key, value);
},
},
},
}
);
5、页面中使用 Store,示例代码如下:
<template>
<view class="container">
<view>用户名称:{{ userNameStore.name }}</view>
<view>
<button type="default" size="mini" @click="setUserNameHandle">修改用户名称</button>
</view>
</view>
</template>
<script setup lang="ts">
import { userName } from '@/store'
const userNameStore = userName()
// 修改用户名称
const setUserNameHandle = () => {
userNameStore.setUserName('欢迎使用 uni-app')
}
</script>
<style lang="scss">
.container {
padding: 30rpx;
view {
margin-top: 30rpx;
}
button {
margin-right: 30rpx;
}
}
</style>
二、网页端
1、安装 pinia 和 pinia-plugin-persistedstate
npm install pinia
2、创建 store
- 1、在项目src目录中创建 stores文件夹,并创建index.ts文件,文件实例代码如下:
import { createPinia } from "pinia";
// 创建 pinia
const pinia = createPinia();
// 导出 pinia
export default pinia;
// 模块统一导出
export * from "./modules/userInfo";
3、在 main.ts 中挂载 pinia,示例代码如下:
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
// 导入 pinia
import pinia from "./stores/index";
// 持久化存储
import { createPersistedState } from 'pinia-plugin-persistedstate'
pinia.use(
createPersistedState({
auto: true // 启动所有 Store 默认持久化
})
)
// 挂载 pinia
const app = createApp(App);
app.use(pinia);
app.mount("#app");
4、创建业务 Store,示例代码如下:
import { defineStore } from 'pinia'
export const userStore = defineStore('user', {
state: () => ({
userInfo: {
userName: '中华人民共和国',
age: 30
}
}),
actions: {
/**
* 修改用户信息方法
* @param { string } userName 用户名称
* @param { number } age 年龄
*/
changeUserInfo(userName: string, age: number) {
this.userInfo.userName = userName
this.userInfo.age = age
}
},
getters: {
/**
* 获取用户信息方法
* @param state
* @returns
*/
getUserInfo: (state) => state.userInfo
}
})
5、页面中使用 Store,示例代码如下:
<template>
<el-row class="mb-4">
<el-button type="primary">{{ age }}</el-button>
<el-button type="warning" @click="changeAge">新增</el-button>
<el-button type="warning" @click="resetPiniaHandle">重置</el-button>
</el-row>
</template>
<script setup lang="ts">
import { userStore } from '@/stores'
const userInfo = userStore()
const { age, changeAge } = toRefs(userInfo)
// 重置方法
const resetPiniaHandle = () => {
userInfo.$reset()
}
</script>
<style lang="scss" scoped></style>
6、持久化配置
import { defineStore } from 'pinia'
export const userStore = defineStore('user', {
state: () => ({
userName: '中华人民共和国',
age: 30
}),
actions: {
/**
* 修改用户信息方法
* @param { string } userName 用户名称
*/
changeUserName(userName: string) {
this.userName = userName
},
/**
* 修改年龄方法
* @param { number } age 年龄
*/
changeAge() {
this.age++
}
},
getters: {
/**
* 获取用户信息方法
* @param state
* @returns
*/
getUserName: (state) => state.userName,
/**
* 获取年龄方法
* @param state
* @returns
*/
getAge: (state) => state.age
},
// persist: true // 默认全部字段持久化
//按需配置数据持久化 这里指定变量num保持持久化
persist: {
//默认名称为当前store唯一标识 这里即home
key: 'ageStore',
//默认localStorage 本地储存
//这里建议临时储存sessionStorage 也可写成window.sessionStorage
storage: sessionStorage,
//默认当前store里的所有变量都持久化
paths: ['age']
}
})