Vue 项目配置自动更新,发布后自动刷新页面

653 阅读1分钟

今天用户反馈使用页面的时候,有时候点击没反应,排查下来,是因为发布版本的时候,用户那边没有加载最新的文导致的,然后根据思路,做了这个自动更新的功能


[效果预览]

demo.webwlx.cn/#/update

实现思路

1. 把当前版本的编译时间,通过环境变量的方式保存起来

打开 vite.config.js

import dayjs from 'dayjs';
import fs from 'fs';
//  获取当前时间戳
const VERSION_TIME = dayjs().format('YYYY-MM-DD HH:mm:ss');
// 把 VERSION_TIME 写入到 public/version.json 文件中
fs.writeFileSync('./public/version.json', JSON.stringify({ VERSION_TIME }));
export default defineConfig({
	// 添加环境变量
	define: {
		'import.meta.env.VERSION_TIME': JSON.stringify(VERSION_TIME),
	},
});

2.封装update.vue,我这里使用的是antd的弹窗,如果其他组件库可自行修改

<template>
	<!-- <a-button @click="startUpdate" type="primary">更新</a-button> -->
	<a-modal v-model:visible="updateDialog" width="300px" :footer="null" title="更新提示" :closable="false" :keyboard="false" :maskClosable="false">
		<h1 class="text-xl">发现新版本</h1>
		<p class="mt-2">
			发布时间:<span class="text-red-500">{{ newVersionTime }}</span>
		</p>
		<a-button type="primary" shape="round" class="ml-auto mr-auto mt-10 block">{{ count }} 秒后 更新</a-button>
	</a-modal>
</template>
<script setup>
import axios from 'axios';
import { onMounted, ref } from 'vue';
import dayjs from 'dayjs';
const interCheck = ref(null);
const count = ref(5);
const newVersionTime = ref(dayjs().format('YYYY-MM-DD HH:mm:ss'));
const updateDialog = ref(false);
function startCheck() {
	// 每 3s 检查一次更新
	if (!interCheck.value) {
		interCheck.value = setInterval(() => {
			checkVersion();
		}, 5000);
	}
}
function endCheck() {
	clearInterval(interCheck.value);
	interCheck.value = null;
}
async function checkVersion() {
	//  axios.defaults.headers 不加载缓存
	const publicVersion = await axios.get(location.origin + '/version.json?t=' + Date.now(), {
		headers: {
			'Cache-Control': 'no-cache',
			Pragma: 'no-cache',
			Expires: '-1',
		},
	});
	const NEW_VERSION_TIME = publicVersion.data.VERSION_TIME;
	const VERSION_TIME = import.meta.env.VERSION_TIME;
	if (NEW_VERSION_TIME && new Date(NEW_VERSION_TIME) > new Date(VERSION_TIME)) {
		endCheck();
		newVersionTime.value = NEW_VERSION_TIME;
		startUpdate();
	}
}

async function startUpdate() {
	// 开始自动更新倒计时
	count.value = 5;
	updateDialog.value = true;
	// 倒计时
	const timer = setInterval(() => {
		count.value--;
		if (count.value === 1) {
			clearInterval(timer);
			// 强制刷新页面
			location.reload(true);
		}
	}, 1000);
}

onMounted(() => {
	startCheck();
});
</script>


3.在app.vue引入

<template>
	<Update></Update>
	<div id="app">
		<router-view></router-view>
	</div>
</template>
<script setup>
import Update from './components/update.vue';
</script>