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('安装事件不可用')
		}
	}
相关推荐
Domain-zhuo7 分钟前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
小丁爱养花15 分钟前
前端三剑客(三):JavaScript
开发语言·前端·javascript
ZwaterZ23 分钟前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
码农六六23 分钟前
vue3封装Element Plus table表格组件
javascript·vue.js·elementui
徐同保28 分钟前
el-table 多选改成单选
javascript·vue.js·elementui
快乐小土豆~~28 分钟前
el-input绑定点击回车事件意外触发页面刷新
javascript·vue.js·elementui
周三有雨35 分钟前
【面试题系列Vue07】Vuex是什么?使用Vuex的好处有哪些?
前端·vue.js·面试·typescript
建群新人小猿1 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
djk88882 小时前
Layui Table 行号
前端·javascript·layui
今天啥也没干2 小时前
使用 Sparkle 实现 macOS 应用自定义更新弹窗
前端·javascript·swift