Vue多頁(yè)項(xiàng)目實(shí)現(xiàn)在每次版本更新時(shí)做提示的解決方案
一、遇到的問題
項(xiàng)目中使用懶加載方式加載組件,在新部署鏡像后,由于瀏覽器緩存又去加載舊的js chunk,但是之時(shí)舊的js chunk已經(jīng)不存在,加載不出來造成bug

二、解決方式
在每次部署后更改版本號(hào),在頁(yè)面做提示,當(dāng)前版本又更新,提示用戶刷新頁(yè)面
(1)可以使用的方案有哪些
- 使用輪訓(xùn)查詢最新的版本號(hào)做對(duì)比
- 使用websocket
- 使用service worker
(2)最終采用了什么方案
最終使用了方案1;原因是配置簡(jiǎn)單方便;缺點(diǎn)是會(huì)加大服務(wù)器壓力!~ (1)在public中創(chuàng)建一個(gè)version.json文件,寫清楚各個(gè)模塊的版本, 我這里項(xiàng)目vue多頁(yè)的,每個(gè)項(xiàng)目都要單獨(dú)版本管理
{
"A項(xiàng)目": {
"version": "1.18.0",
"description": ""
},
"B項(xiàng)目": {
"version": "1.18.0",
"description": ""
},
"C項(xiàng)目": {
"version": "1.18.0",
"description": ""
},
}
(2)創(chuàng)建一個(gè)全局的versionUpdate方法,來檢測(cè)版本是否更新
import 'element-plus/dist/index.css'
import { ElMessageBox } from 'element-plus'
/**
* 版本信息接口
*/
type TVersionInfo = {
[moduleName: string]: TModuleInfo
}
/**
* 模塊版本存儲(chǔ)信息
*/
type TModuleInfo = {
version: string
description?: string
}
/**
* 基于version.json的版本檢測(cè)和更新提示工具
*/
export class VersionUpdateService {
private versionCheckInterval: number | null = null
private readonly CHECK_INTERVAL = 5 * 60 * 1000 // 5分鐘檢查一次
private moduleName: string
private storageKey: string
constructor(moduleName: string = 'home') {
this.moduleName = moduleName
this.storageKey = `module-version-${moduleName}`
}
/**
* 獲取模塊版本信息
*/
private getModuleVersionInfo(): TModuleInfo | null {
const stored = localStorage.getItem(this.storageKey)
return stored ? JSON.parse(stored) : null
}
/**
* 保存模塊版本信息
*/
private saveModuleVersionInfo(info: TModuleInfo): void {
localStorage.setItem(this.storageKey, JSON.stringify(info))
}
/**
* 從version.json獲取版本信息(統(tǒng)一從 public/version.json 中按模塊名讀?。?
*/
private async fetchVersionInfo(): Promise<TModuleInfo | null> {
try {
const fullUrl = `${window.location.origin}/version.json?t=${Date.now()}`
console.log(`[${this.moduleName}] 正在獲取version.json: ${fullUrl}`)
const response = await fetch(fullUrl, {
method: 'GET',
cache: 'no-cache',
headers: { 'Content-Type': 'application/json' }
})
if (!response.ok) {
console.warn(`[${this.moduleName}] 無法獲取version.json: ${response.status} ${response.statusText}`)
return null
}
// 期望 public/version.json 結(jié)構(gòu)為:{ "A項(xiàng)目": { ... }, "B項(xiàng)目": { ... }, "C項(xiàng)目": { ... }, ... }
const indexData = await response.json() as TVersionInfo
console.log(`[${this.moduleName}] 獲取到版本信息:`, indexData)
return indexData[this.moduleName]
} catch (error) {
console.warn(`[${this.moduleName}] 獲取version.json失敗:`, error)
return null
}
}
/**
* 檢查是否有新版本
*/
private async checkForUpdate(): Promise<boolean> {
const currentVersionInfo = await this.fetchVersionInfo()
if (!currentVersionInfo) {
console.warn(`[${this.moduleName}] 無法獲取當(dāng)前版本信息,跳過檢測(cè)`)
return false
}
const storedInfo = this.getModuleVersionInfo()
if (!storedInfo) {
// 第一次檢查,保存當(dāng)前版本信息
this.saveModuleVersionInfo(currentVersionInfo)
console.log(`[${this.moduleName}] 首次檢查,保存版本信息`)
return false
}
const versionUpdated = currentVersionInfo.version !== storedInfo.version
if (versionUpdated) {
console.log(`[${this.moduleName}] 檢測(cè)到版本更新:`, currentVersionInfo)
return true
}
console.log(`[${this.moduleName}] 當(dāng)前為最新版本:`, currentVersionInfo)
return false
}
/**
* 顯示更新提示
*/
private showUpdateNotification(currentVersionInfo: TModuleInfo): void {
const moduleTitle = this.getModuleTitle(this.moduleName)
const currentModuleInfo = currentVersionInfo
const message = `有新版本可用:${currentModuleInfo.version}\n${currentModuleInfo.description}`
ElMessageBox.confirm(
message,
`${moduleTitle}版本更新`,
{
confirmButtonText: '立即刷新',
cancelButtonText: '稍后提醒',
type: 'info',
center: true
}
).then(() => {
this.updateVersionInfo(currentVersionInfo)
this.reloadPage()
}).catch(() => {
console.log(`[${this.moduleName}] 用戶選擇稍后更新`)
})
}
/**
* 獲取模塊標(biāo)題
*/
private getModuleTitle(moduleName: string): string {
const titles: Record<string, string> = {
'A項(xiàng)目': 'A項(xiàng)目名稱'
...
}
return titles[moduleName] || moduleName
}
/**
* 更新版本信息
*/
private async updateVersionInfo(currentVersionInfo: TModuleInfo): Promise<void> {
this.saveModuleVersionInfo(currentVersionInfo)
console.log(`[${this.moduleName}] 版本信息已更新:`, currentVersionInfo.version)
}
/**
* 刷新頁(yè)面
*/
private reloadPage(): void {
if ('caches' in window) {
caches.keys().then(names => {
names.forEach(name => {
caches.delete(name)
})
})
}
setTimeout(() => {
window.location.reload()
}, 100)
}
/**
* 開始定期檢查
*/
public startVersionCheck(): void {
this.performVersionCheck()
this.versionCheckInterval = window.setInterval(() => {
this.performVersionCheck()
}, this.CHECK_INTERVAL)
}
/**
* 執(zhí)行版本檢查
*/
private async performVersionCheck(): Promise<void> {
const currentVersionInfo = await this.fetchVersionInfo()
if (!currentVersionInfo) return
const hasUpdate = await this.checkForUpdate()
if (hasUpdate) {
this.showUpdateNotification(currentVersionInfo)
}
}
/**
* 停止版本檢查
*/
public stopVersionCheck(): void {
if (this.versionCheckInterval) {
clearInterval(this.versionCheckInterval)
this.versionCheckInterval = null
}
}
/**
* 獲取所有模塊版本信息(調(diào)試用)
*/
public static getAllModuleVersions(): Record<string, TModuleInfo | null> {
const modules = ['A項(xiàng)目'...]
const result: Record<string, TModuleInfo | null> = {}
modules.forEach(module => {
const key = `module-version-${module}`
const stored = localStorage.getItem(key)
result[module] = stored ? JSON.parse(stored) : null
})
return result
}
/**
* 清除指定模塊的版本信息
*/
public static clearModuleVersion(moduleName: string): void {
const key = `module-version-${moduleName}`
localStorage.removeItem(key)
console.log(`已清除模塊 [${moduleName}] 的版本信息`)
}
/**
* 初始化版本更新檢測(cè)
*/
public static init(moduleName: string = 'home'): VersionUpdateService {
const service = new VersionUpdateService(moduleName)
service.startVersionCheck()
return service
}
}
/**
* 初始化版本更新檢測(cè)
*/
export const initVersionUpdateJson = (moduleName?: string) => {
return VersionUpdateService.init(moduleName || 'home')
}
/**
* 兼容舊版本的導(dǎo)出
*/
export const initVersionUpdate = initVersionUpdateJson
3、在每個(gè)模塊中的main.ts中引入使用這個(gè)方法
import { initVersionUpdateJson } from '@/utils/VersionUpdate'
// 初始化版本檢測(cè)
initVersionUpdateJson('chess') // 這里傳入的是項(xiàng)目名稱
到此這篇關(guān)于Vue多頁(yè)項(xiàng)目實(shí)現(xiàn)在每次版本更新時(shí)做提示的解決方案的文章就介紹到這了,更多相關(guān)Vue多頁(yè)項(xiàng)目版本更新時(shí)做提示內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue打包后dist文件在本地啟動(dòng)運(yùn)行的步驟
這篇文章主要給大家介紹了關(guān)于vue打包后dist文件在本地啟動(dòng)運(yùn)行的簡(jiǎn)單步驟,文中通過代碼示例以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09
vue2滾動(dòng)條加載更多數(shù)據(jù)實(shí)現(xiàn)代碼
本篇文章主要介紹了vue2滾動(dòng)條加載更多數(shù)據(jù)實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
Vue3實(shí)現(xiàn)富文本內(nèi)容導(dǎo)出為Word文檔
這篇文章主要為大家詳細(xì)介紹了Vue3如何通過純前端方案將富文本內(nèi)容直接導(dǎo)出為符合中文排版規(guī)范的 Word 文檔,有需要的小伙伴可以參考下2025-03-03
vue實(shí)現(xiàn)表格增刪改查效果的實(shí)例代碼
本篇文章主要介紹了vue實(shí)現(xiàn)增刪改查效果的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
vue通過指令(directives)實(shí)現(xiàn)點(diǎn)擊空白處收起下拉框
這篇文章主要介紹了vue通過指令(directives)實(shí)現(xiàn)點(diǎn)擊空白處收起下拉框,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
vue數(shù)據(jù)對(duì)象length屬性未定義問題
這篇文章主要介紹了vue數(shù)據(jù)對(duì)象length屬性未定義問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

