vue实现项目部署成功之后提示用户刷新页面
1. 项目根目录新建 version.js
require("fs").writeFileSync("./public/version.txt", new Date().getTime().toString())
2. 改写package.json中打包命令
"scripts": {
"dev": "vue-cli-service serve",
"prod": "vue-cli-service serve --mode production",
"build:prod": "node version.js && vue-cli-service build --mode production",
"format": "prettier --write \"src/**/*.js\" \"src/**/*.vue\""
},
3. 新建src/utils/watchUpdate.js文件
import Modal from "./updateModal.vue";
import Vue from "vue";
let time = 0;
let version = "";
let prodFlag = process.env.NODE_ENV === "production";
let timer = null;
let timerFuncion = async () => {
if (time >= 5) {
clearInterval(timer);
return (timer = null);
}
let res = await fetch(`/version.txt?v=${new Date().getTime().toString()}`)
.then((res) => {
return res.json();
})
.catch((err) => {
console.log(err);
return clearTimer();
});
if (!version) {
version = res;
console.log("首次加载版本", version);
} else if (version != res) {
console.log("发现版本更新", version);
let MessageConstructor = Vue.extend(Modal);
let instance = new MessageConstructor({
data: {},
});
instance.id = new Date().getTime().toString();
instance.$mount();
document.body.appendChild(instance.$el);
return clearTimer();
}
time++;
};
let moveFunction = () => {
if (prodFlag) {
time = 0;
if (!timer) {
timer = setInterval(timerFuncion, 1000);
}
}
};
if (prodFlag) timer = setInterval(timerFuncion, 5000);
window.addEventListener("mousemove", moveFunction);
let clearTimer = () => {
clearInterval(timer);
window.removeEventListener("mousemove", moveFunction);
timer = null;
};
4. 新建 src/utils/updateModal.vue文件
<template>
<div class="update-modal">
<div class="title">系统更新🚀</div>
<div class="content">
系统已更新,请刷新页面(请在刷新前注意保存当前页面数据)。
</div>
<div class="actions">
<button @click="handleAfterLeave">忽略</button>
<button @click="refresh">刷新</button>
</div>
</div>
</template>
<script>
export default {
methods: {
handleAfterLeave() {
this.$destroy(true);
this.$el.parentNode.removeChild(this.$el);
},
refresh() {
this.handleAfterLeave();
location.reload(true);
},
},
};
</script>
<style scoped>
.update-modal {
user-select: none;
position: fixed;
//right: 10px;
//bottom: 20px;
top: 33%;
left: 0;
right: 0;
margin: auto;
max-width: 300px;
min-width: 250px;
width: 50%;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
border-radius: 5px;
padding: 10px 15px;
animation: shakeY 1.5s linear;
z-index: 99999;
}
@keyframes shakeY {
from,
to {
transform: translate3d(0, 0, 0);
}
10%,
30%,
50%,
70%,
90% {
transform: translate3d(0, -10px, 0);
}
20%,
40%,
60%,
80% {
transform: translate3d(0, 10px, 0);
}
}
.shakeY {
animation-name: shakeY;
}
.update-modal .title {
height: 50px;
line-height: 50px;
font-size: 18px;
margin-bottom: 10px;
}
.update-modal .content {
text-indent: 2em;
font-size: 16px;
}
.update-modal .actions {
display: flex;
justify-content: flex-end;
margin-top: 30px;
}
.update-modal .actions button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.1s;
font-weight: 500;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
padding: 10px 20px;
font-size: 14px;
border-radius: 4px;
margin-left: 10px;
}
.update-modal .actions button:last-child {
background-color: #409eff;
color: #fff;
border-color: #409eff;
}
</style>
5. main.js中导入watchUpdate文件
import "./utils/watchUpdate.js";