vue+vite生产环境更新提示

前言

之前写过一个基于轮询+vite构建产物实现一个生产环境的提示更新
前端自动检测更新

但是呢这种方式要写的代码太多了,而且如果处理不当容易出现问题,维护成本比较高

今天就用一个更简单的方法实现

一、vite-plugin-pwa

vite-plugin-pwa

vite-plugin-pwa 实现是基于workbox实现的

二、使用步骤

使用方式极其简单

先安装

javascript 复制代码
pnpm add -D vite-plugin-pwa
pnpm add workbox-window

然后根据官网的描述解决一些ts类型的问题

由于vite8基于Rolldown,在编译的时候找不到workbox-window,所以需要手动安装

然后在vite.config.ts进行配置

javascript 复制代码
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { VitePWA } from "vite-plugin-pwa";
// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    VitePWA({
      // 🟢 改为 prompt 模式:发现新版本时挂起,等待用户确认后再更新
      registerType: "prompt",
      workbox: {
        globPatterns: ["**/*.{js,css,html,ico,png,svg,jpg,jpeg,json,woff2}"],
        maximumFileSizeToCacheInBytes: 50 * 1024 * 1024,
      },
    }),
  ],
});

最后写一个提示弹框

javascript 复制代码
<!-- ReloadPrompt.vue -->
<template>
  <!-- 当检测到需要更新时,展示这个精美的提示通知条 -->
  <transition name="slide-up">
    <div v-if="needRefresh" class="pwa-toast" role="alert">
      <div class="message">
        <span class="icon">🚀</span>
        <span>系统检测到新版本,请刷新以获取最佳体验!</span>
      </div>
      <div class="actions">
        <!-- 点击"立即刷新",触发 SW 更新和页面重启 -->
        <button class="btn-refresh" @click="handleUpdate">立即刷新</button>
        <!-- 用户也可以选择关闭提示,下次打开时再用新的 -->
        <button class="btn-close" @click="needRefresh = false">稍后</button>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { useRegisterSW } from "virtual:pwa-register/vue";

// 使用插件提供的组合式 API
const { needRefresh, updateServiceWorker } = useRegisterSW({
  onRegistered(r) {
    console.log("SW 注册成功,开始守护页面");
    // 进阶:每隔 10s,主动去服务器拉取一次 sw.js,看看有没有新版本发布
    if (r) {
      setInterval(() => {
        r.update();
      }, 10 * 1000);
    }
  },
  onRegisterError(error) {
    console.error("SW 注册失败:", error);
  },
});

const handleUpdate = () => {
  // 核心:调用此方法,SW 将接管新控制权,并自动执行 window.location.reload()
  updateServiceWorker(true);
};
</script>

<style scoped>
.pwa-toast {
  position: fixed;
  right: 24px;
  bottom: 24px;
  margin: 16px;
  padding: 16px 24px;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  z-index: 99999;
  background-color: #ffffff;
  box-shadow:
    0 10px 25px -5px rgba(0, 0, 0, 0.1),
    0 8px 10px -6px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 350px;
}
.message {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #1e293b;
  font-weight: 500;
}
.actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
button {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  border: none;
  transition: all 0.2s;
}
.btn-refresh {
  background-color: #3b82f6;
  color: white;
}
.btn-refresh:hover {
  background-color: #2563eb;
}
.btn-close {
  background-color: #f1f5f9;
  color: #64748b;
}
.btn-close:hover {
  background-color: #e2e8f0;
}

/* 动画效果 */
.slide-up-enter-active,
.slide-up-leave-active {
  transition:
    transform 0.3s ease,
    opacity 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
  transform: translateY(30px);
  opacity: 0;
}
</style>

官网也有案例,可以直接拿来使用

结果展示

初始化

当我更新页面重新build,就会有提示更新的弹框

点击立即刷新就会更新页面

代码仓库

相关推荐
weixin_3823952342 分钟前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__1 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.1 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~2 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华3 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子5 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅6 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni6 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学7 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端