vue前端版本更新后消息通知的实现

MicLon原创2023年6月1日
大约 3 分钟

问题及需求

前端版本迭代后,用户如果不刷新页面,无法及时获取到最新的版本,这时候就需要一个消息通知的功能,告知用户当前版本已经过期,需要刷新页面。

想要实现这个功能,需要解决以下几个问题:

  1. 如何判断当前版本是否过期?
  2. 如何在用户不刷新页面的情况下,实时获取到最新的版本后,通知用户刷新页面?

解决方案

  • 如何判断当前版本是否过期?

项目采用vue3+vite进行开发,可以通过vite打包时,生成version.json文件,文件包含了当前版本号,可以通过发起请求获取到该文件,然后与当前本地缓存的版本号进行比较,如果不一致,则说明当前版本已经过期。

为此,笔者翻阅了vite-pluginopen in new window的开发文档,通过插件开放的几个钩子函数,可以实现在打包时,生成version.json文件,同时也可以将版本号插入到index.html中,方便前端获取。

为了让插件更加通用,笔者将插件开发成了一个npm包,vite-plugin-version-outputopen in new window,可以通过npm安装使用。

在使用时,只需要在vite.config.ts中引入插件即可:

// vite.config.ts
import { defineConfig } from 'vite'
import { vitePluginVersionOutput } from 'vite-plugin-version-output'

export default defineConfig({
  plugins: [
    vitePluginVersionOutput({
      // name: 'test-app',
      // version: '0.0.1',
      json: {
        enable: true,
        fileName: 'version.json'
      },
      html: {
        enable: true,
        toMeta: true,
        toConsole: true,
        toGlobal: true
      },
    })
  ],
})

具体的配置说明可以移步到githubopen in new window

  • 如何在用户不刷新页面的情况下,实时获取到最新的版本后,通知用户刷新页面?

有了获取最新版本号的能力,接下来只需要在项目里,在某个条件下(路由切换/定时轮询)的时候,发起请求获取最新版本号,然后与本地缓存的版本号进行比较,如果不一致,则说明当前版本已经过期,需要通知用户刷新页面。

import axios from 'axios'
import { useSessionStorage } from '@vueuse/core'

const useVersion = defineStore(
  'version',
  {
    state: () => ({
      version: useSessionStorage('version', null),
      needUpgrade: false
    }),
    actions: {
      async check() {
        const resp = await axios.get('version.json').catch(err => {
          console.error('checkVersion error: ', err)
          this.needUpgrade = false
        })
        // 当本地不存在 version 时,将 version 设置为当前版本
        if (this.version === null) {
          this.version = resp.data.version
          this.needUpgrade = false
        } else {
          // 比对本地版本与远程版本
          this.needUpgrade = this.version !== resp.data.version ? true : false
        }
      },
      async clear() {
        this.version = null
        this.needUpgrade = false
      },
      async upgrade() {
        window.location.reload()
      }
    }
  }
)

export default useVersion

代码还是非常简单的,通过useSessionStorage来缓存版本号,然后通过check方法,发起请求获取最新版本号,与本地缓存的版本号进行比较,如果不一致,needUpgrade设置为true,否则设置为false

那接下来只需要在业务层写个弹窗,提示用户当前版本已经过期,需要刷新页面即可。

最终实现效果

参考

Loading...