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