Vue實(shí)現(xiàn)前端頁(yè)面版本檢測(cè)的示例代碼
為什么需要版本檢測(cè)
1. 解決瀏覽器緩存問題
- 靜態(tài)資源緩存:瀏覽器會(huì)緩存 JS、CSS 等靜態(tài)資源,用戶可能繼續(xù)使用舊版本
- 用戶體驗(yàn)影響:用戶無(wú)法及時(shí)獲取新功能,導(dǎo)致功能缺失或操作異常
2. 保障功能一致性
- 功能同步:確保所有用戶都能使用最新的功能和修復(fù)
- 數(shù)據(jù)一致性:避免因版本差異導(dǎo)致的數(shù)據(jù)不一致問題
3. 提升用戶體驗(yàn)
- 主動(dòng)提醒:在新版本發(fā)布后主動(dòng)通知用戶更新
- 無(wú)縫升級(jí):減少用戶手動(dòng)刷新頁(yè)面的需求
版本檢測(cè)核心思路

整體架構(gòu)
構(gòu)建階段 → 版本文件生成 → 運(yùn)行時(shí)檢測(cè) → 版本對(duì)比 → 用戶提醒
技術(shù)實(shí)現(xiàn)要點(diǎn)
1. 版本標(biāo)識(shí)生成
- 構(gòu)建時(shí)生成:每次打包時(shí)生成唯一的版本標(biāo)識(shí)
- 時(shí)間戳方案:使用時(shí)間戳確保每次構(gòu)建版本號(hào)唯一
2. 版本文件部署
- JSON 格式:將版本信息保存為
version.json文件 - 靜態(tài)訪問:通過 HTTP 請(qǐng)求可直接訪問版本文件
3. 客戶端檢測(cè)機(jī)制
- 定時(shí)輪詢:定期檢查服務(wù)器版本文件
- 版本對(duì)比:比較本地緩存版本與服務(wù)器版本
- 智能提醒:僅在版本不一致時(shí)提醒用戶
版本檢測(cè)實(shí)現(xiàn)步驟
步驟一:構(gòu)建版本文件生成腳本
創(chuàng)建 build-version.js 文件:
// build-version.js (自動(dòng)生成版本文件腳本)
const fs = require('fs')
const path = require('path')
// 方案A:使用時(shí)間戳作為版本標(biāo)識(shí)(最簡(jiǎn)單,確保每次打包唯一)
const version = new Date().getTime().toString()
// 版本文件內(nèi)容
const versionJson = {
version: version,
updateTime: new Date().toLocaleString() // 可選:添加更新時(shí)間,便于排查
}
// 寫入version.json文件(項(xiàng)目根目錄)
const versionPath = path.resolve(__dirname, 'public', 'version.json')
fs.writeFileSync(versionPath, JSON.stringify(versionJson, null, 2), 'utf-8')
console.log(`? 自動(dòng)生成版本文件成功,版本號(hào):${version}`)
步驟二:修改構(gòu)建命令
在 package.json 中修改構(gòu)建命令:
{
"scripts": {
"build:prod": "node build-version.js && vue-cli-service build"
}
}
步驟三:配置 Vue 構(gòu)建過程
在 vue.config.js 中添加版本文件復(fù)制配置:
chainWebpack(config) {
// ... 其他配置
// 復(fù)制 version.json 到 dist 目錄
config.plugin('copy')
.tap(args => {
const hasVersionJson = args[0].some(item => item.from === 'version.json')
if (!hasVersionJson) {
args[0].push({
from: path.resolve(__dirname, 'public/version.json'),
to: path.resolve(__dirname, 'dist/version.json')
})
}
return args
})
}
步驟四:實(shí)現(xiàn)版本檢測(cè)工具類
創(chuàng)建 src/utils/versionUpdate.js:
// src/utils/versionUpdate.js
import { Notification } from 'element-ui'
/**
* 版本更新檢測(cè)工具類(僅生產(chǎn)環(huán)境啟用輪詢,內(nèi)置環(huán)境判斷)
*/
class VersionUpdate {
constructor(options = {}) {
this.config = {
versionFileUrl: '/version.json', // 版本文件地址
localVersionKey: 'cmpVersion', // 本地存儲(chǔ)的版本號(hào)key
disableFetchCache: true, // 禁用Fetch緩存
pollInterval: 5 * 60 * 1000, // 5分鐘輪詢一次
hasNotified: false // 是否已提醒過用戶有新版本
}
Object.assign(this.config, options)
// 定時(shí)輪詢定時(shí)器
this.pollTimer = null
// 識(shí)別當(dāng)前環(huán)境(Vue CLI 4 自動(dòng)注入的環(huán)境變量)
this.isProduction = process.env.NODE_ENV === 'production'
}
/**
* 核心方法:執(zhí)行版本檢測(cè)
*/
async checkVersion(isInit = false) {
try {
if (this.config.hasNotified) return false
const localVersion = localStorage.getItem(this.config.localVersionKey) || ''
const fetchOptions = {}
if (this.config.disableFetchCache) {
fetchOptions.cache = 'no-cache'
}
const response = await fetch(this.config.versionFileUrl, fetchOptions)
if (!response.ok) {
throw new Error(`版本文件請(qǐng)求失敗,狀態(tài)碼:${response.status}`)
}
const latestVersionInfo = await response.json()
const serverVersion = latestVersionInfo.version
if (isInit) {
this.cacheLatestVersion(serverVersion)
return true
}
if (serverVersion && serverVersion !== localVersion) {
this.config.hasNotified = true
console.log('有新版本可用', latestVersionInfo)
Notification({
title: '?? 有新版本可用',
dangerouslyUseHTMLString: true,
message: `<p style="font-size:12px;">建議點(diǎn)擊刷新頁(yè)面,以獲取最新功能和修復(fù)</p> <p style="color:#cccccc;font-size:12px;">更新時(shí)間:${latestVersionInfo.updateTime}</p>`,
duration: 0,
customClass: 'check-version-notify',
onClick: () => {
this.forceRefreshPage()
},
onClose: () => {
this.resetNotifyFlag()
}
})
return true
} else {
// 版本一致時(shí),重置提醒標(biāo)記,便于后續(xù)輪詢檢測(cè)新版本
this.config.hasNotified = false
// console.log('當(dāng)前已是最新版本,已緩存最新版本號(hào)')
return false
}
} catch (error) {
console.warn('版本檢測(cè)異常,不影響應(yīng)用運(yùn)行:', error.message)
return false
}
}
/**
* 啟動(dòng)定時(shí)輪詢檢測(cè)(內(nèi)置環(huán)境判斷:僅生產(chǎn)環(huán)境生效)
*/
async startPolling() {
// 核心:非生產(chǎn)環(huán)境,直接返回,不啟動(dòng)輪詢
if (!this.isProduction) {
console.log('當(dāng)前為非生產(chǎn)環(huán)境,不啟動(dòng)版本檢測(cè)輪詢')
return
}
// 生產(chǎn)環(huán)境:正常啟動(dòng)輪詢
this.stopPolling() // 先停止已有輪詢,避免重復(fù)啟動(dòng)
this.checkVersion(true) // 立即執(zhí)行一次檢測(cè)
this.pollTimer = setInterval(() => {
this.checkVersion()
}, this.config.pollInterval)
console.log(`生產(chǎn)環(huán)境版本輪詢檢測(cè)已啟動(dòng),每隔${this.config.pollInterval / 1000 / 60}分鐘檢測(cè)一次`)
}
/**
* 停止定時(shí)輪詢檢測(cè)
*/
stopPolling() {
if (this.pollTimer) {
clearInterval(this.pollTimer)
this.pollTimer = null
console.log('版本輪詢檢測(cè)已停止')
}
}
/**
* 重置提醒標(biāo)記
*/
resetNotifyFlag() {
this.config.hasNotified = false
}
// 緩存最新版本號(hào)
cacheLatestVersion(version) {
localStorage.setItem(this.config.localVersionKey, version)
this.resetNotifyFlag()
}
// 強(qiáng)制刷新頁(yè)面
forceRefreshPage() {
window.location.reload(true)
}
}
const versionUpdateInstance = new VersionUpdate()
export { VersionUpdate, versionUpdateInstance }
export default versionUpdateInstance
創(chuàng)建自定義.check-version-notify的版本檢測(cè)全局樣式:

// 版本檢測(cè)通知樣式
.check-version-notify{
border: 3px solid transparent !important;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.6) !important;
backdrop-filter: blur(5px);
&:hover{
border: 3px solid $--color-primary !important;
}
.el-notification__icon{
font-size: 18px;
height: 18px;
}
.el-notification__title{
font-size: 14px;
line-height: 18px;
}
.el-notification__group{
margin-left: 8px;
}
}
步驟五:在應(yīng)用入口啟動(dòng)版本檢測(cè)
在 App.vue 或合適的入口文件中啟動(dòng)版本檢測(cè):
import versionUpdate from '@/utils/versionUpdate'
...
mounted() {
versionUpdate.startPolling()
},
beforeDestroy() {
versionUpdate.stopPolling()
}
到此這篇關(guān)于Vue實(shí)現(xiàn)前端頁(yè)面版本檢測(cè)的示例代碼的文章就介紹到這了,更多相關(guān)Vue頁(yè)面版本檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)公共組件傳值并及時(shí)監(jiān)聽到數(shù)據(jù)更新視圖
這篇文章主要介紹了vue實(shí)現(xiàn)公共組件傳值并及時(shí)監(jiān)聽到數(shù)據(jù)更新視圖方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
淺談el-table中使用虛擬列表對(duì)對(duì)表格進(jìn)行優(yōu)化
我們會(huì)經(jīng)常使用表格,如果數(shù)據(jù)量大就直接可以分頁(yè),如果多條可能會(huì)影響表格的卡頓,那么應(yīng)該如何進(jìn)行優(yōu)化,感興趣的可以了解一下2021-08-08
vue實(shí)現(xiàn)在線預(yù)覽pdf文件和下載(pdf.js)
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)在線預(yù)覽pdf文件和下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
vue2.0實(shí)現(xiàn)音樂/視頻播放進(jìn)度條組件
這篇文章主要為大家詳細(xì)介紹了vue2.0實(shí)現(xiàn)音樂和視頻播放進(jìn)度條組件的思路及具體實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
element-ui自定義message-box自定義樣式不生效的解決
這篇文章主要介紹了element-ui自定義message-box自定義樣式不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
基于Vue3與免費(fèi)滿血版DeepSeek實(shí)現(xiàn)無(wú)限滾動(dòng)+懶加載+瀑布流模塊及優(yōu)化過程
在進(jìn)行非完全標(biāo)準(zhǔn)化數(shù)據(jù)的可視化展示時(shí),瀑布流是一種經(jīng)常被采用的展示方法,瀑布流能夠有效地將不同大小規(guī)格的內(nèi)容以一種相對(duì)規(guī)整的方式呈現(xiàn)出來(lái),本文給大家介紹了基于Vue3與免費(fèi)滿血版DeepSeek實(shí)現(xiàn)無(wú)限滾動(dòng)+懶加載+瀑布流模塊,需要的朋友可以參考下2025-03-03

