在 Pinia 中使用中间件(通过自定义插件模拟),除了在 action 执行前后记录状态外,还可以实现多种实用功能,以下是一些常见的应用场景:
1. 权限验证
在执行某些敏感操作的 action 之前,中间件可以进行权限验证,确保用户具有执行该操作的权限。若权限不足,则阻止 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) => {
// 假设这里有一个函数用于检查权限
const hasPermission = checkUserPermission(actionName);
if (hasPermission) {
return await originalAction(...args);
} else {
console.error(`You don't have permission to perform ${
actionName}`);
return null;
}
};
});
};
function checkUserPermission(actionName) {
// 这里可以实现具体的权限检查逻辑,例如从本地存储获取用户角色等
// 示例:假设只有 'admin' 角色可以执行 'deleteData' action
const userRole = localStorage.getItem('userRole');
if (actionName === 'deleteData' && userRole!== 'admin') {
return false;
}
return true;
}
2. 错误处理与重试机制
在 action 执行过程中,如果出现错误,中间件可以捕获错误并进行统一处理,还可以实现重试机制,尝试重新执行 action 一定次数。
// errorHandlingMiddleware.js
export const errorHandlingMiddleware = (context) => {
const {
store } = context;
const MAX_RETRIES = 3;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
let retries = 0;
while (retries < MAX_RETRIES) {
try {
return await originalAction(...args);
} catch (error) {
retries++;
console.error(`Action ${
actionName} failed (attempt ${
retries}):`, error);
if (retries === MAX_RETRIES) {
console.error(`Action ${
actionName} failed after ${
MAX_RETRIES} attempts.`);
throw error;
}
// 可以在这里添加重试间隔,例如使用 setTimeout
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
};
});
};
3. 日志记录与分析
除了记录状态,中间件还可以记录 action 的执行时间、传入的参数等信息,用于后续的分析和调试。
// loggingMiddleware.js
export const loggingMiddleware = (context) => {
const {
store } = context;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
const startTime = Date.now();
console.log(`Action ${
actionName} started with args:`, args);
try {
const result = await originalAction(...args);
const endTime = Date.now();
const executionTime = endTime - startTime;
console.log(`Action ${
actionName} completed in ${
executionTime}ms. Result:`, result);
return result;
} catch (error) {
const endTime = Date.now();
const executionTime = endTime - startTime;
console.error(`Action ${
actionName} failed in ${
executionTime}ms. Error:`, error);
throw error;
}
};
});
};
4. 缓存处理
在执行某些频繁调用且结果相对稳定的 action 时,中间件可以实现缓存机制,避免重复的计算或请求。
// cachingMiddleware.js
const cache = {
};
export const cachingMiddleware = (context) => {
const {
store } = context;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
const cacheKey = `${
actionName}-${
JSON.stringify(args)}`;
if (cache[cacheKey]) {
console.log(`Using cached result for action ${
actionName}`);
return cache[cacheKey];
}
try {
const result = await originalAction(...args);
cache[cacheKey] = result;
return result;
} catch (error) {
console.error(`Action ${
actionName} failed:`, error);
throw error;
}
};
});
};
5. 状态同步
如果应用中有多个数据源或需要与外部系统同步状态,中间件可以在 action 执行后将状态同步到其他地方。
// stateSyncMiddleware.js
export const stateSyncMiddleware = (context) => {
const {
store } = context;
Object.keys(store.$actions).forEach((actionName) => {
const originalAction = store.$actions[actionName];
store.$actions[actionName] = async (...args) => {
const result = await originalAction(...args);
// 假设这里有一个函数用于同步状态到外部系统
syncStateToExternalSystem(store.$state);
return result;
};
});
};
function syncStateToExternalSystem(state) {
// 实现具体的状态同步逻辑,例如发送请求到后端更新数据
console.log('Syncing state to external system:', state);
}
通过这些中间件功能,可以增强应用的健壮性、安全性和可维护性。