1.在src根目录下新建auto-update.js
/*
* @Description: 自动更新
*/
// const timeData = 60 * 1000 // 检查间隔时间
const timeData = 10 * 1000 // 检查间隔时间
let hidden = false // 页面是否隐藏
let setTimeoutId
let needTip = true // 默认开启提示
let oldScript = []
let newScript = []
const getHtml = async () => {
const html = await fetch('/').then(res => res.text()) //读取index html
return html
}
// const scriptReg = /<script.*src=["'](?<src>[^"']+)/gm
const parserScript = (html) => {
const reg = new RegExp(/<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/ig) //script正则
return html.match(reg) //匹配script标签
}
const init = async () => {
const html = await getHtml()
// console.log("🚀 ~ file: auto-update.js:31 ~ init ~ html:", html)
oldScript = parserScript(html)
}
const compareScript = async (oldArr, newArr) => {
console.log(oldArr,'oldArr')
const base = oldArr.length
// 去重
const arr = Array.from(new Set(oldArr.concat(newArr)))
let needRefresh = false
// 如果新旧length 一样无更新
// 否则通知更新
console.log(base,'base')
console.log(arr.length,'arr')
if (arr.length !== base) {
console.warn('更新了!!!!!!, arr.length !== base', arr.length !== base)
needRefresh = true
}
return needRefresh
}
// 自动更新
const autoUpdate = async () => {
setTimeoutId = setTimeout(async () => {
const newHtml = await getHtml()
// console.log("🚀 ~ file: auto-update.js:89 ~ newHtml:", newHtml)
newScript = parserScript(newHtml)
console.log("🚀 ~ file: auto-update.js:79 ~ newScript:", newScript)
// 页面隐藏了就不检查更新
if (!hidden) {
const willRefresh = await compareScript(oldScript, newScript)
console.log(willRefresh, 'willRefresh')
console.log(needTip,'needTip')
if (willRefresh && needTip) {
console.log('dabu')
// 延时更新,防止部署未完成用户就刷新空白
setTimeout(() => {
// ----弹框确认---先简单点弹框确认,可以用注释内的,跳过右下角通知的内容(Step2、3)
const result = confirm('🚀发现新版本,请及时更新(ctrl+F5)')
if (result) {
sessionStorage.setItem('version', version)
location.reload() // 刷新当前页
}
// --------------
//*****右下角通知提示 */
// window.dispatchEvent(
// new CustomEvent("onmessageUpdate", {
// detail: {
// msg: "发现系统版本更新,请刷新页面~",
// version: version
// },
// })
// )
//******************* */
}, 10000)
needTip = false // 关闭更新提示,防止重复提醒
}
}
console.log("🚀 ~ file: auto-update.js:90 ~ autoUpdate ~ needTip: ", needTip)
if (needTip) {
console.warn('needTip autoUpdate');
autoUpdate()
}
}, timeData)
}
// 停止检测更新
const stop = () => {
if (setTimeoutId) {
clearTimeout(setTimeoutId)
setTimeoutId = ''
}
}
// 开始检查更新
const start = async () => {
init()
console.log('start0000000000')
autoUpdate()
console.log('start1111111111')
// 监听页面是否隐藏
document.addEventListener('visibilitychange', () => {
hidden = document.hidden
// console.log("🚀 ~ file: auto-update.js:64 ~ document.addEventListener ~ hidden, needTip:", hidden, needTip)
// 页面隐藏了就不检查更新。或者已经有一个提示框了,防止重复提示。
if (!hidden && needTip) {
autoUpdate()
} else {
stop()
}
})
}
export default { start }
2.在main.js中引用
// 引入自动更新提醒
import autoUpdate from '@/auto-update'
// 非生产环境使用
process.env.VUE_APP_ENV !== 'production' && autoUpdate.start()
3.新建vue页面CnNotify.vue
<template>
<div class="cn_notify">
<div class="content">
<i class="el-icon-message-solid"></i>
{{ msg }}
</div>
<div class="footer">
<el-row class="btnBox">
<el-button type="primary" @click="onSubmit">确认刷新</el-button>
<el-button @click="cancle">我知道了</el-button>
</el-row>
</div>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: '',
},
},
data() {
return {};
},
created() { },
methods: {
// 点击确定更新
onSubmit() {
location.reload() // 刷新
},
// 关闭
cancle() {
this.$parent.close();
},
},
};
</script>
<style lang='scss' scoped>
.cn_notify {
.content {
padding: 20px 0;
}
.footer {
display: flex;
justify-content: center;
}
}
</style>
<style lang='scss'>
.versionNotifyStyle {
.el-notification__content {
width: 280px !important;
}
}
</style>
4.在app.vue中引用
import CnNotify from "@/components/CnNotify.vue"
components: {
CnNotify, // 注册组件
},
mounted(){
this.watchUpdate()
}
methods:{
watchUpdate() {
window.addEventListener("onmessageUpdate", (res) => {
let msg = res.detail.msg,
version = res.detail.version
console.log(version,'5555555')
this.$notify({
title: "版本更新提示",
duration: 0,
position: "bottom-right",
dangerouslyUseHTMLString: true,
message: this.$createElement("CnNotify", {
// 使用自定义组件
ref: "CnNotify",
props: {
msg: msg,
version: version
},
}),
customClass: 'versionNotifyStyle', //自定义类名
})
})
},
}