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" ;