实现思路:通过版本号对比触发更新策略,结合用户交互提升体验
// src/utils/versionControl.js
import { version } from '../../package.json';
import { ElMessageBox } from 'element-plus';
const VERSION_KEY = 'app_version';
export const checkVersionUpdate = async () => {
const currentVersion = version;
const storedVersion = localStorage.getItem(VERSION_KEY);
if (storedVersion !== currentVersion) {
try {
await ElMessageBox.confirm(
`检测到新版本 v${currentVersion},建议立即更新以获得最佳体验`,
'版本更新',
{
confirmButtonText: '立即更新',
cancelButtonText: '稍后提醒',
type: 'warning',
draggable: true,
}
);
// 强制刷新逻辑
localStorage.clear();
sessionStorage.clear();
localStorage.setItem(VERSION_KEY, currentVersion);
window.location.reload();
} catch (e) {
// 用户选择暂不更新时记录日志
console.warn('用户暂未更新版本');
}
}
};
调用时机:
// main.js
import { checkVersionUpdate } from './utils/versionControl';
const initApp = async () => {
const app = createApp(App);
// ...其他初始化配置
await checkVersionUpdate();
app.mount('#app');
};
initApp();
优势:
配置优化(基于pinia-plugin-persistedstate
):
// src/stores/piniaPersist.js
import { createPersistedState } from 'pinia-persistedstate-plugin';
export const piniaPersist = createPersistedState({
storage: {
getItem: (key) => {
try {
const data = localStorage.getItem(key);
return data ? JSON.parse(data) : null;
} catch (e) {
console.error('Storage parse error:', e);
return null;
}
},
setItem: (key, value) => {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (e) {
console.error('Storage save error:', e);
}
},
},
serializer: {
serialize: (value) => {
// 可在此处添加加密逻辑
return btoa(JSON.stringify(value));
},
deserialize: (value) => {
try {
return JSON.parse(atob(value));
} catch (e) {
return value;
}
},
},
// 精细化控制需要持久化的state
paths: ['auth.userInfo', 'preferences.theme'],
});
安全增强:
// 在serializer中集成加密算法
import CryptoJS from 'crypto-js';
const SECRET_KEY = 'your-secret-key';
serializer: {
serialize: (value) => {
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(value),
SECRET_KEY
).toString();
return btoa(encrypted);
},
deserialize: (value) => {
try {
const decrypted = CryptoJS.AES.decrypt(
atob(value),
SECRET_KEY
).toString(CryptoJS.enc.Utf8);
return JSON.parse(decrypted);
} catch (e) {
return {};
}
}
}
// 按模块划分存储空间
const userPersist = createPersistedState({
key: 'user_store',
storage: localStorage,
});
const systemPersist = createPersistedState({
key: 'system_store',
storage: sessionStorage,
});
核心措施:
// 对所有写入localStorage的数据进行转义
function sanitizeInput(input) {
return input.replace(/</g, '<').replace(/>/g, '>');
}
// 在存储前处理
localStorage.setItem('key', sanitizeInput(value));
// 通过Proxy限制存储访问
const secureStorage = new Proxy(localStorage, {
get(target, prop) {
if (['getItem', 'setItem'].includes(prop)) {
return (...args) => {
if (args[0].startsWith('secure_')) {
throw new Error('Access denied');
}
return target[prop](...args);
};
}
return target[prop];
}
});
// 带过期时间的存储
const setWithExpiry = (key, value, ttl) => {
const now = new Date();
const item = {
value: value,
expiry: now.getTime() + ttl,
};
localStorage.setItem(key, JSON.stringify(item));
};
const getWithExpiry = (key) => {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
const now = new Date();
if (now.getTime() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
};
·