在 Pinia 里本身没有直接的中间件概念,但可通过自定义插件模拟中间件的功能。以下详细介绍编写和使用中间件(即自定义插件)的步骤与示例。
1. 理解中间件功能
中间件常用于在 action 执行前后插入额外逻辑,像日志记录、权限验证、错误处理等。
2. 创建中间件(自定义插件)
下面给出几个不同功能的中间件示例:
日志记录中间件
此中间件会在 action 执行前后记录日志,方便调试。
// logMiddleware.js
export const logMiddleware = (context) => {
const {
store } = context;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
// 记录 action 开始执行及参数
console.log(`Action ${
actionName} 开始执行,参数:`, args);
try {
const result = await originalAction(...args);
// 记录 action 执行成功及结果
console.log(`Action ${
actionName} 执行成功,结果:`, result);
return result;
} catch (error) {
// 记录 action 执行失败及错误信息
console.error(`Action ${
actionName} 执行失败,错误信息:`, error);
throw error;
}
};
});
};
权限验证中间件
该中间件在执行 action 前检查用户权限,若权限不足则阻止执行。
// permissionMiddleware.js
export const permissionMiddleware = (context) => {
const {
store } = context;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
// 模拟权限检查函数
if (checkUserPermission(actionName)) {
return await originalAction(...args);
} else {
console.error(`没有权限执行 ${
actionName}`);
return null;
}
};
});
};
function checkUserPermission(actionName) {
// 示例:从本地存储获取用户角色进行权限判断
const userRole = localStorage.getItem('userRole');
// 假设只有管理员能执行 'deleteItem' action
if (actionName === 'deleteItem' && userRole!== 'admin') {
return false;
}
return true;
}
3. 在 Pinia 中使用中间件
在创建 Pinia 实例时,使用 use
方法应用中间件。
// main.js
import {
createPinia } from 'pinia';
import {
logMiddleware } from './logMiddleware';
import {
permissionMiddleware } from './permissionMiddleware';
const pinia = createPinia();
// 使用日志记录中间件
pinia.use(logMiddleware);
// 使用权限验证中间件
pinia.use(permissionMiddleware);
export default pinia;
4. 创建并使用 Pinia store
创建一个简单的 store 并在组件中使用,触发 action 时中间件会生效。
// counterStore.js
import {
defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
},
decrement() {
this.count--;
}
}
});
<template>
<div>
<p>Count: {
{ counterStore.count }}</p>
<button @click="counterStore.increment">增加</button>
<button @click="counterStore.decrement">减少</button>
</div>
</template>
<script setup>
import { useCounterStore } from './counterStore';
const counterStore = useCounterStore();
</script>
代码解释
- 中间件函数:接收
context
对象,其中包含store
。遍历 store 的所有 action,重写每个 action 函数,在其前后添加中间件逻辑。 - Pinia 实例:创建 Pinia 实例后,通过
use
方法应用中间件,这样所有使用该 Pinia 实例的 store 都会应用这些中间件。 - Pinia store:定义包含 action 的 store,在组件中使用 store 并触发 action 时,中间件会执行相应逻辑。
通过上述步骤,你就能在 Pinia 中编写并使用中间件来增强状态管理功能。