当前端项目部署更新后,用户仍然在使用旧网页,导致容易出现数据异常;
因此采用检测版本号的方式,当新发布的版本号大于当前版本号,则会在右下角弹窗提示更新;用户点击“刷新按钮”等价于刷新页面。此时index.html经过刷新后,hex文件能采取新的js、css等。
原理:
1、vue项目打包时,在 dist部署文件夹下生成一个 version.txt文件,内容“1.0.1”,取自package.json中的version;
2、在vue路由中判断(也可以用多线程定时器),通过api请求的方式获取txt中的内容;比较版本;
3、弹窗提示更新(现为提示,也可改为强制更新);第一次进入localStorage保存,再次部署更新后提示;
打包处理函数文件
import fs, { writeFileSync } from 'fs-extra';
import path from 'path';
import pkg from '../../package.json';
// 省略打包逻辑。。。
// 写入文件
writeFileSync(path.resolve(process.cwd(), 'dist/version.txt'), pkg.version);
router.ts
import { updateVerFn } from ./updateVer.ts
router.beforeEach(async (to, from, next) => {
// 省略其它处理(权限判断、动态路由等等)。。。
updateVerFn();
}
updateVer.ts
import { notification } from 'ant-design-vue';
import { debounce } from 'lodash-es';
import { h } from 'vue';
// // 读取文件
function loadFileFn(url) {
const xhr = new XMLHttpRequest();
const okStatus = document.location.protocol === 'file:' ? 0 : 200;
xhr.open('GET', url, false);
xhr.overrideMimeType('text/html;charset=utf-8'); // 默认为utf-8
xhr.send(null);
return xhr.status === okStatus ? xhr.responseText : '';
}
function compareVersions(v1, v2) {
const parts1 = v1.split('.').map(Number);
const parts2 = v2.split('.').map(Number);
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const num1 = parts1[i] || 0;
const num2 = parts2[i] || 0;
if (num1 > num2) return 1;
if (num1 < num2) return -1;
}
return 0;
}
export const updateVerFn = debounce(function () {
let verT = loadFileFn(`/version.txt?v=${new Date().getTime()}`); // 增加时间戳防止缓存
console.log('versionT', verT);
const verTL = window.localStorage.getItem('verTL') || '';
if (!verTL) {
window.localStorage.setItem('verTL', verT);
return false;
}
if (compareVersions(verT, verTL) > 0) {
notification.open({
message: `系统更新🚀`,
description: h('div', [
h('span', { style: 'font-size:12px' }, '系统有了新的版本,请刷新页面哦!'),
h(
'button',
{
style: 'background-color:#ffedd5;border-radius:10px;cursor:pointer;',
onclick: () => {
window.localStorage.setItem('verTL', verT);
window.location.reload();
},
},
'刷新',
),
]),
placement: 'bottomRight',
style: { width: '200px' },
});
}
}, 3000);