vue实现项目部署成功之后提示用户刷新页面

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", // 这样会在public目录下生成version.txt文件,记录当前时间戳
    "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);
  }
  // fetch 部署后同层级的version文件 并且加上时间戳参数 防止去访问本地硬盘的缓存
  let res = await fetch(`/version.txt?v=${
     new Date().getTime().toString()}`)
    .then((res) => {
   
      return res.json();
    })
    .catch((err) => {
   
      console.log(err);
      return clearTimer(); // 访问失败就完全关闭轮询
    });
  // console.log("存储的version:" + version)
  // console.log("获取到version:" + res)
  // console.log("比较结果:", res == version)

  // 首次加载网页的时候 存储第一份version
  if (!version) {
   
    version = res;
    console.log("首次加载版本", version);
  } else if (version != res) {
   
    console.log("发现版本更新", version);
    // 弹出更新提示 发现verison文件更新了 就代表新部署了
    // 借鉴Element的Message实现挂载vue组件到页面上
    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++;
};
// 检测鼠标是否移动 移动代表用户活跃中 把轮询比较用的次数一直清0
let moveFunction = () => {
   
  // 判断在生产环境下才执行
  if (prodFlag) {
   
    time = 0;
    // 长时间挂机后 不在轮询的网页 在鼠标活跃于窗口的时候重新检测
    if (!timer) {
   
      timer = setInterval(timerFuncion, 1000);
    }
  }
};
// 当被main.js 引用的时候 开始轮询于监听鼠标移动事件
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();
      // window.location.replace(window.location.href); //没有刷新缓存
      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"; // 监听页面更新

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-10 04:28:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-10 04:28:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-10 04:28:01       82 阅读
  4. Python语言-面向对象

    2024-01-10 04:28:01       91 阅读

热门阅读

  1. qt QLibraryInfo

    2024-01-10 04:28:01       52 阅读
  2. SQLAlchemy 中的会话(Session)缓存详解

    2024-01-10 04:28:01       50 阅读
  3. 1135. 新年好 (Dijkstra,dfs枚举)

    2024-01-10 04:28:01       55 阅读
  4. 从零开始构建区块链:我的区块链开发之旅

    2024-01-10 04:28:01       50 阅读
  5. 洛谷 P8682 [蓝桥杯 2019 省 B] 等差数列

    2024-01-10 04:28:01       47 阅读