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