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"; // 监听页面更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/294189.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CF1909_C. Heavy Intervals题解

CF1909_C. Heavy Intervals题解 题目传送门&#xff08;Problem - C - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1909/problem/C&#xff09;。 题目翻译如下&#xff1a;&#xff08;图片来源&a…

STM32 CubeMX产生的程序架构

使用STM32CubeMX产生启动相关代码&#xff0c;配置各种外设。在后续程序开发过程中&#xff0c;有可能使用STM32CubeMX逐步产生使用的代码&#xff0c;为了将其产生的代码和我们程序隔离&#xff0c;一种可行的程序架构如下&#xff1a; 在此架构中&#xff0c;STM32CubeMX产生…

还在用if-else? 用策略模式干掉它

策略模式&#xff08;Strategy Pattern&#xff09; 策略模式是一种行为设计模式&#xff0c;它将一组行为转换为对象&#xff0c; 并使其在原始上下文对象内部能够相互替换。大白话就是比如我写一个登录业务&#xff0c;目前需要满足能通过系统内、微信等平台进行登录&#x…

前端页面锚点跳转

一&#xff0c;页面 二&#xff0c;获取需要跳转的标签class或者id 三&#xff0c;调用跳转方法 如果你的标签有唯一的ID&#xff0c;那么用getElementById方法更好 点击即可跳转锚点

在 Walrus 上轻松集成 OpenTofu

OpenTofu 是什么&#xff1f; OpenTofu 是一个开源的基础设施即代码&#xff08;IaC&#xff09;框架&#xff0c;被提出作为 Terraform 的替代方案&#xff0c;并由 Linux 基金会管理。OpenTofu 的问世为应对 HashiCorp 将 Terraform 的许可证从 Mozilla Public License v2.0…

内网穿透的应用-使用Docker本地部署可编辑导航页结合内网穿透实现远程访问

文章目录 1. 使用Docker搜索镜像2. 下载镜像3. 查看镜像4. 启动容器5. 浏览器访问6. 远程访问6.1 内网穿透工具安装6.2 创建远程连接公网地址6.3 使用固定二级子域名地址远程访问 今天和大家分享如何使用Docker本地部署一个开源的简约风格网址导航页&#xff0c;支持五种搜索引…

GeoServe本地部署结合内网穿透实现远程访问Web管理界面

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除、插入…

域名流量被劫持怎么办?如何避免域名流量劫持?

随着互联网不断发展&#xff0c;流量成为线上世界的巨大财富。然而一种叫做域名流量劫持的网络攻击&#xff0c;将会在不经授权的情况下控制或重定向一个域名的DNS记录&#xff0c;导致用户在访问一个网站时&#xff0c;被引导到另一个不相关的网站&#xff0c;从而劫持走原网站…

查询slurm集群各个节点的运行情况

引言 slurm系统是一个集群&#xff0c;它原生的使用方式可以参考之前写的《slurm初识》和《slurm快速入门》。有时候我们想知道我们能申请哪些节点&#xff0c;以及各个节点的使用情况。 原生的指令大概有这两个&#xff0c;一个是使用squeue的方式列举出当前的工作列表。 …

Windows通过注册表修改socket缓冲区大小的方法

在 Windows 通过修改注册表来更改 UDP 缓冲区的大小&#xff0c;按照以下步骤进行操作&#xff1a; 打开注册表编辑器&#xff1a;按下 Win R 键&#xff0c;然后输入 "regedit" 并点击 "确定"。 导航到以下路径&#xff1a;HKEY_LOCAL_MACHINE\System\C…

每日汇评:今天市场重点都转移到美国非农就业数据

周四美元走势摇摆不定&#xff1b; 到目前为止&#xff0c;欧元兑美元仍受到1.0900区域的支撑&#xff1b; 市场的下一个风险事件是美国就业数据的发布&#xff1b; 欧元兑美元在周四成功恢复了上涨动力&#xff0c;并短暂重返1.0970区间&#xff0c;在连续四个交易日的空头主导…

微服务应用可观测性解决方案介绍

目录 一、可观测性出现背景 二、什么是可观测性&#xff08;Observability&#xff09; 2.1 可观测性的不同解析 2.1.1 百度维基解析 2.1.2 IBM解析 2.1.3 CNCF&#xff08;云原生计算机基金会&#xff09;组织解析 2.1.4 我的个人理解 2.2 可观测性和监控的区别与联系 …

C++完成使用map Update数据 非二进制

1、在LXMysql.h和LXMysql.cpp分别定义和编写关于pin语句的代码 //获取更新数据的sql语句 where语句中用户要包含where 更新std::string GetUpdatesql(XDATA kv, std::string table, std::string where); std::string LXMysql::GetUpdatesql(XDATA kv, std::string table, std…

OpenHarmony内存泄漏指南 - 解决问题(综合)

本系列文章旨在提供定位与解决OpenHarmony应用与子系统内存泄露的常见手段与思路&#xff0c;将会分成几个部分来讲解。首先我们需要掌握发现内存泄漏问题的工具与方法&#xff0c;以及判断是否可能存在泄漏。接着需要掌握定位泄漏问题的工具&#xff0c;以及抓取trace、分析tr…

我们正迎来计算基因的巨大变革,即将到来的不仅是量子技术——

计算机是围绕逻辑构建的&#xff1a;利用电路执行数学运算。逻辑是围绕诸如加法器——这种将两个数字相加的基本电路&#xff0c;而构建的。 今天的微处理器和计算机历史初期的所有微处理器都是如此。这可以追溯到算盘&#xff0c;在某些基本层面上&#xff0c;这和你闪亮的游戏…

前端根据URL地址实现下载(txt,图片,word,xlsx,ppt)

前端根据URL地址实现下载&#xff08;txt&#xff0c;图片&#xff0c;word&#xff0c;xlsx&#xff0c;ppt&#xff09; 一、对于txt,图片类的二、对于word&#xff0c;xlsx&#xff0c;ppt类的1.a标签可以实现下载2. window.open&#xff08;&#xff09; 一、对于txt,图片类…

软件推荐:MobaXterm

介绍 MobaXterm 是远程计算的终极工具箱&#xff0c;它提供了几乎所有重要的远程网络工具&#xff0c;SSH、RDP、FTP、VNC&#xff0c;只要你能想到的&#xff0c;都可以在MobaXterm中找到。除了海量协议外&#xff0c;MobaXterm 还支持安装额外的插件来扩展其功能。 软件官网…

技术查漏补缺(1)Logback

一、下定义&#xff1a;Logback是一个开源的日志组件 二、Logback的maven <!--这个依赖直接包含了 logback-core 以及 slf4j-api的依赖--> <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><v…

MySQL-数据库概述

数据库相关概念&#xff1a; 数据库(DateBase)简称DB,就是一个存储数据的仓库&#xff0c;数据有组织的进行存储。 数据库分为关系型数据库简称RDBMS和非关系型数据库 关系型数据库简称RDBMS:建立在关系模型的基础上&#xff0c;由多张相互连接的二维表组成的数据库.简单来说…

D6208双向直流马达驱动芯片 用于IPC产品,可兼容BA6208,噪声低 ,工作电源电压范围宽。

D6208 是一块单片双向马达驱动电路&#xff0c;它使用TTL电平的逻辑信号就能控制卡式录音机和其它电子设备中的双向马达。该电路由一个逻辑部分和一个功率输出部分组成。逻辑部分控制马达正、反转向及制动&#xff0c;功率输出部分根据逻辑控制能提供100mA&#xff08;典型值&a…