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('安装事件不可用')
		}
	}
相关推荐
weixin_516875655 分钟前
使用 axios 拦截器实现请求和响应的统一处理(附常见面试题)
前端·javascript·vue.js
皮卡穆7 分钟前
JavaScript 变量作用域与函数调用机制:var 示例详解
javascript
H_HX12611 分钟前
https服务器访问http资源报Mixed Content混合内容错误
前端·vue.js·安全策略·https访问http
羊小猪~~19 分钟前
前端入门一之CSS知识详解
前端·javascript·css·vscode·前端框架·html·javas
哪 吒23 分钟前
华为OD机试 - 无重复字符的元素长度乘积的最大值(Python/JS/C/C++ 2024 C卷 100分)
javascript·python·华为od
ReBeX25 分钟前
【GeoJSON在线编辑平台】(1)创建地图+要素绘制+折点编辑+拖拽移动
前端·javascript·gis·openlayers·webgis
今天也想MK代码34 分钟前
在Swift开发中简化应用程序发布与权限管理的解决方案——SparkleEasy
前端·javascript·chrome·macos·electron·swiftui
V+zmm101341 小时前
社区养老服务小程序ssm+论文源码调试讲解
java·服务器·前端·javascript·小程序·毕业设计·1024程序员节
卡布叻_星星1 小时前
同一个页面击穿element样式后,会影响同样组件的使用
前端·vue.js·elementui
加油小吃货1 小时前
定义全局键盘监听事件,el-dialog中删除不可用
javascript·vue.js·elementui