uniapp 使用vue/pwa

复制代码
vue add @vue/pwa

src下创建service-worker.js

复制代码
/* eslint-disable no-undef*/
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js')
if (workbox) {
  console.log(`Yay! Workbox is loaded 🎉`)
} else {
  console.log(`Boo! Workbox didn't load 😬`)
}
 
workbox.core.setCacheNameDetails({
  prefix: 'ochase-search',
  suffix: 'v1.0.0'
})
workbox.core.skipWaiting() // 强制等待中的 Service Worker 被激活
workbox.core.clientsClaim() // Service Worker 被激活后使其立即获得页面控制权
workbox.precaching.precacheAndRoute(self.__precacheManifest || []) // 设置预加载
 
// 缓存web的css资源
workbox.routing.registerRoute(
  // Cache CSS files
  /.*\.css/,
  // 使用缓存,但尽快在后台更新
  new workbox.strategies.StaleWhileRevalidate({
    // 使用自定义缓存名称
    cacheName: 'css-cache'
  })
)
 
// 缓存web的js资源
workbox.routing.registerRoute(
  // 缓存JS文件
  /.*\.js/,
  // 使用缓存,但尽快在后台更新
  new workbox.strategies.StaleWhileRevalidate({
    // 使用自定义缓存名称
    cacheName: 'js-cache'
  })
)
 
// 缓存web的图片资源
workbox.routing.registerRoute(
  /\.(?:png|gif|jpg|jpeg|svg)$/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'images',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60 // 设置缓存有效期为30天
      })
    ]
  })
)
 
// 如果有资源在其他域名上,比如cdn、oss等,这里做单独处理,需要支持跨域
workbox.routing.registerRoute(
  /^https:\/\/cdn\.ochase\.com\/.*\.(jpe?g|png|gif|svg)/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'cdn-images',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 5 * 24 * 60 * 60 // 设置缓存有效期为5天
      })
    ],
    fetchOptions: {
      credentials: 'include' // 支持跨域
    }
  })
)

在main.js 添加代码

复制代码
// #ifdef VUE3
import './src/registerServiceWorker'

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/src/service-worker.js').then(registration => {
      console.log('Service Worker registered with scope:', registration.scope);
    }).catch(error => {
      console.error('Service Worker registration failed:', error);
    })
  })
}

import { createSSRApp } from 'vue'
export function createApp() {
	const app = createSSRApp(App)
	return {
		app
	}
}
// #endif

在pulic添加 manifest.json

复制代码
{
	"short_name": "name",
	"name": "name",
	"icons": [{
		"src": "/static/logo.png",
		"type": "image/png",
		"sizes": "72x72"
	},
	{
		"src": "/static/2.png",
		"type": "image/png",
		"sizes": "320x320"
	}],
	"id": "/?source=pwa",
	"start_url": "index.html",
	"background_color": "#3367D6",
	"display": "standalone",
	"scope": "/",
	"theme_color": "#3367D6",
	"shortcuts": [{
			"name": "",
			"short_name": "",
			"description": "",
			"url": "/today?source=pwa",
			"icons": [{ "src": "/static/1.png", "sizes": "96x96" }]
		},
		{
			"name": "",
			"short_name": "",
			"description": "",
			"url": "/tomorrow?source=pwa",
			"icons": [{ "src": "/static/1.png", "sizes": "96x96" }]
		}
	],
	"description": "",
	"screenshots": [{
			"src": "",
			"type": "image/png",
			"sizes": "320x320",
			"form_factor": "narrow"
		},
		{
			"src": "",
			"type": "image/jpg",
			"sizes": "320x320",
			"form_factor": "wide"
		}
	]
}

在index.html添加

复制代码
//主题颜色		
<meta name="theme-color" content="#00142A">
//引入manifest.json
<link rel="manifest" href="/public/manifest.json" />

然后运行 支持https协议和localhost

判断当前处于h5 或者pwajianti

复制代码
<script setup>
	import { onMounted } from 'vue'
	onMounted(() => {
		console.log(checkIfPWA() ? 'PWA 模式' : 'H5 模式');
		if (checkIfPWA()) {
			uni.navigateTo({
				url: '/pages/live/index'
			})
		} else {
			uni.navigateTo({
				url: '/pages/pwa/index'
			})
		}
	})

	const checkIfPWA = () => {
		return (
			window.matchMedia('(display-mode: standalone)').matches ||
			window.navigator.standalone === true ||
			document.referrer.startsWith('android-app://')
		)
	}
</script>

监听下载事件

复制代码
onMounted(() => {
  window.addEventListener('beforeinstallprompt', (event) => {
    // 防止浏览器默认的安装提示
    event.preventDefault()
    installPromptEvent.value = event;  // 保存事件对象
    console.log('安装事件已保存:', installPromptEvent.value)
  })
})

	const install = () => {
		if (installPromptEvent.value) {
			// 显示pwa安装提示
			installPromptEvent.value.prompt()

			// 监听用户选择结果
			installPromptEvent.value.userChoice.then((choiceResult) => {
				if (choiceResult.outcome === 'accepted') {
					console.log('用户接受了安装')
				} else {
					console.log('用户拒绝了安装')
				}
				installPromptEvent.value = null
			});
		} else {
			console.log('安装事件不可用')
		}
	}
相关推荐
eason_fan32 分钟前
Git 大小写敏感性问题:一次组件重命名引发的CI构建失败
前端·javascript
前端付豪2 小时前
1、震惊!99% 前端都没搞懂的 JavaScript 类型细节
前端·javascript·面试
朝与暮2 小时前
js符号(Symbol)
前端·javascript
大怪v3 小时前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
遂心_5 小时前
为什么 '1'.toString() 可以调用?深入理解 JavaScript 包装对象机制
前端·javascript
王同学QaQ5 小时前
Vue3对接UE,通过MQTT完成通讯
javascript·vue.js
华仔啊5 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端
程序员鱼皮6 小时前
刚刚 Java 25 炸裂发布!让 Java 再次伟大
java·javascript·计算机·程序员·编程·开发·代码
Asort6 小时前
JavaScript 从零开始(五):运算符和表达式——从零开始掌握算术、比较与逻辑运算
前端·javascript
一枚前端小能手6 小时前
🚀 缓存用错了网站更慢?前端缓存策略的5个致命误区
前端·javascript