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('安装事件不可用')}}