实现原理:当我们点击路由的时候,动态生成一个引入的版本资源文件的标签到文档中,资源文件里面有一个获取版本的函数getVersion, 成功插入到文档中之后,会调用函数 getVersion, 这个函数会对比本地的版本号,如果不一样,则强制刷新网页。
// version.js
import { Loading } from 'element-ui'
import common from '@/utils/common'
function handleVersion () {
if (process.env.NODE_ENV !== 'development') {
// 获取版本更新的jsonp回调函数
window.getVersion = version => {
if ((common.getLocalStorage('frontendVersion') && version !== common.getLocalStorage('frontendVersion')) || (window.frontendVersion && version !== window.frontendVersion)) {
Loading.service() // 启动全屏loading
location.reload(true) // 刷新页面
}
common.setLocalStorage('frontendVersion', version) // 保存 以便下次使用判断
window.frontendVersion = version // 保存 以便下次使用判断
}
}
}
function insertVersionFile () {
if (process.env.NODE_ENV !== 'development') {
const assets = '/'
const scriptCollection = document.getElementsByTagName('script')
// 判断是否已经有 version.js 文件, 如果有, 先删掉资源引入
const scriptAry = [...scriptCollection]
scriptAry.some(v => {
const flag = v.src.indexOf('version.js') !== -1
if (flag) {
(v.remove && v.remove()) || (v.removeNode && v.removeNode(true))
}
return flag
})
const versionScript = document.createElement('script')
versionScript.src = location.origin + assets + 'version.js?v=' + new Date().getTime()
const s = document.getElementsByTagName('script')[0]
s.parentNode.insertBefore(versionScript, s)
}
}
handleVersion()
export { insertVersionFile }
// build.version.js
const path = require('path')
const fs = require('fs')
const version = new Date().getTime()
const content = `getVersion('${version}')`
// 创建版本文件
fs.writeFile(`${path.resolve(__dirname, './dist')}/version.js`, content, err => (err ? console.log(err) : console.log('版本文件创建成功')))
// 路由拦截里面调用函数
insertVersionFile()
// package.json
"scripts": {
...
"build:prod": "vue-cli-service build --mode production && node ./build.version.js",
...
},
备注: 这个只是浏览器的缓存,如果nginx那里有缓存,则需要加上
location / {
...
add_header Cache-Control no-store;
...
}