vue 部署提示用户更新

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', //自定义类名

        })

      })

    },

}

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值