一、Vue 项目中的实现
1. 创建版本检测工具
javascript
复制代码
// src/utils/versionChecker.js
const VERSION = '1.0.0'; // 与package.json中版本一致
const CHECK_INTERVAL = 30 * 60 * 1000; // 30分钟检查一次
export default {
async checkVersion() {
try {
const res = await fetch(`/version.json?t=${Date.now()}`);
const { version, updateContent } = await res.json();
if (this.compareVersions(VERSION, version) === -1) {
this.showUpdateDialog(version, updateContent);
return true;
}
return false;
} catch (error) {
console.error('版本检查失败:', error);
return false;
}
},
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 p1 = parts1[i] || 0;
const p2 = parts2[i] || 0;
if (p1 < p2) return -1;
if (p1 > p2) return 1;
}
return 0;
},
showUpdateDialog(newVersion, updateContent) {
// 使用Vue的动态组件创建弹窗
const UpdateDialog = {
template: `
<div class="update-dialog">
<h3>发现新版本 v${newVersion}</h3>
<p>更新内容: ${updateContent || '优化体验,修复已知问题'}</p>
<div class="actions">
<button @click="updateNow">立即更新</button>
<button @click="closeDialog" v-if="!isForceUpdate">稍后提醒</button>
</div>
</div>
`,
data() {
return {
isForceUpdate: localStorage.getItem('ignoreUpdateCount') >= 3
};
},
methods: {
updateNow() {
window.location.reload(true);
},
closeDialog() {
const count = parseInt(localStorage.getItem('ignoreUpdateCount') || 0) + 1;
localStorage.setItem('ignoreUpdateCount', count);
this.$destroy();
document.body.removeChild(this.$el);
}
}
};
const ComponentClass = Vue.extend(UpdateDialog);
const instance = new ComponentClass().$mount();
document.body.appendChild(instance.$el);
},
init() {
// 页面加载时检查
this.checkVersion();
// 定时检查
setInterval(() => this.checkVersion(), CHECK_INTERVAL);
// 当页面从后台切回时检查
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
this.checkVersion();
}
});
}
};
2. 在 main.js 中初始化
javascript
复制代码
// src/main.js
import Vue from 'vue';
import App from './App.vue';
import versionChecker from './utils/versionChecker';
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
created() {
versionChecker.init();
}
}).$mount('#app');
3. 创建版本文件
json
复制代码
// public/version.json
{
"version": "1.0.1",
"updateContent": "修复了登录页面的安全问题"
}
二、React 项目中的实现
1. 创建版本检测组件
ini
复制代码
// src/components/VersionChecker.js
import React, { useEffect, useState } from 'react';
import { Modal, Button, message } from 'antd';
const VERSION = '1.0.0';
const CHECK_INTERVAL = 30 * 60 * 1000;
const VersionChecker = () => {
const [visible, setVisible] = useState(false);
const [updateInfo, setUpdateInfo] = useState({});
const [ignoreCount, setIgnoreCount] = useState(
parseInt(localStorage.getItem('ignoreUpdateCount') || 0)
);
const 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 p1 = parts1[i] || 0;
const p2 = parts2[i] || 0;
if (p1 < p2) return -1;
if (p1 > p2) return 1;
}
return 0;
};
const checkVersion = async () => {
try {
const res = await fetch(`/version.json?t=${Date.now()}`);
const data = await res.json();
if (compareVersions(VERSION, data.version) === -1) {
setUpdateInfo(data);
setVisible(true);
return true;
}
return false;
} catch (error) {
console.error('版本检查失败:', error);
return false;
}
};
const handleUpdate = () => {
window.location.reload(true);
};
const handleLater = () => {
const newCount = ignoreCount + 1;
setIgnoreCount(newCount);
localStorage.setItem('ignoreUpdateCount', newCount);
setVisible(false);
if (newCount >= 3) {
message.warning('此版本即将不再支持,请尽快更新');
}
};
useEffect(() => {
// 初始化检查
checkVersion();
// 定时检查
const timer = setInterval(checkVersion, CHECK_INTERVAL);
// 页面可见性变化检查
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
checkVersion();
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
clearInterval(timer);
document.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
return (
<Modal
title={`发现新版本 v${updateInfo.version}`}
visible={visible}
onCancel={ignoreCount < 3 ? handleLater : null}
footer={[
ignoreCount < 3 && (
<Button key="later" onClick={handleLater}>
稍后提醒
</Button>
),
<Button key="update" type="primary" onClick={handleUpdate}>
立即更新
</Button>
]}
>
<p>当前版本: v{VERSION}</p>
<p>更新内容: {updateInfo.updateContent || '优化体验,修复已知问题'}</p>
{ignoreCount >= 3 && (
<p style={{ color: 'red' }}>此为强制更新,无法跳过</p>
)}
</Modal>
);
};
export default VersionChecker;
2. 在应用根组件中使用
javascript
复制代码
// src/App.js
import React from 'react';
import VersionChecker from './components/VersionChecker';
function App() {
return (
<div className="App">
{/* 其他应用内容 */}
<VersionChecker />
</div>
);
}
export default App;
三、UniApp 项目中的实现
1. 创建版本检测工具
javascript
复制代码
// utils/versionChecker.js
const VERSION = '1.0.0';
const CHECK_INTERVAL = 30 * 60 * 1000;
export default {
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 p1 = parts1[i] || 0;
const p2 = parts2[i] || 0;
if (p1 < p2) return -1;
if (p1 > p2) return 1;
}
return 0;
},
async checkVersion() {
try {
const res = await uni.request({
url: '/static/version.json',
data: { t: Date.now() }
});
const [error, data] = res;
if (error) throw error;
if (this.compareVersions(VERSION, data.version) === -1) {
this.showUpdateModal(data.version, data.updateContent);
return true;
}
return false;
} catch (error) {
console.error('版本检查失败:', error);
return false;
}
},
showUpdateModal(newVersion, updateContent) {
const ignoreCount = uni.getStorageSync('ignoreUpdateCount') || 0;
const isForceUpdate = ignoreCount >= 3;
uni.showModal({
title: `发现新版本 v${newVersion}`,
content: `当前版本: v${VERSION}\n更新内容: ${updateContent || '优化体验,修复已知问题'}` +
(isForceUpdate ? '\n\n此为强制更新,无法跳过' : ''),
confirmText: '立即更新',
cancelText: isForceUpdate ? '' : '稍后提醒',
showCancel: !isForceUpdate,
success: (res) => {
if (res.confirm) {
// 小程序中使用更新API
if (uni.getUpdateManager) {
const updateManager = uni.getUpdateManager();
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: (res) => {
if (res.confirm) {
updateManager.applyUpdate();
}
}
});
});
} else {
// H5端直接刷新
window.location.reload(true);
}
} else if (res.cancel) {
const newCount = parseInt(ignoreCount) + 1;
uni.setStorageSync('ignoreUpdateCount', newCount);
if (newCount >= 3) {
uni.showToast({
title: '此版本即将不再支持,请尽快更新',
icon: 'none'
});
}
}
}
});
},
init() {
// 应用启动时检查
this.checkVersion();
// 定时检查
setInterval(() => this.checkVersion(), CHECK_INTERVAL);
// 应用从后台切回前台时检查
uni.onAppShow(() => {
this.checkVersion();
});
}
};
2. 在 App.vue 中初始化
xml
复制代码
// App.vue
<script>
import versionChecker from '@/utils/versionChecker';
export default {
onLaunch() {
versionChecker.init();
}
}
</script>
3. 创建版本文件
json
复制代码
// static/version.json
{
"version": "1.0.1",
"updateContent": "修复了支付流程的bug"
}