新項目直接在vue create的時候,選擇PWA模板,就可以啟用PWA,這里主要介紹如果在已有項目中啟用PWA
1.安裝pwa插件
vue add pwa
2.目錄結構
安裝完插件后,會自動生成registerServiceWorker.js文件,另需自己創建service-worker.js配置文件
3.修改registerServiceWorker.js
部分瀏覽器不支持service work,為了保證代碼正常工作運行,通過'serviceWorker' in window.navigator 判斷是否支持
/* eslint-disable no-console */ import { register } from 'register-service-worker' if ('serviceWorker' in window.navigator && process.env.NODE_ENV === 'production') {
//以相對路徑引入service-workere.js register(`./service-worker.js`, { ready () { console.log( 'App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB' ) }, registered () { console.log('Service worker has been registered.') }, cached () { console.log('Content has been cached for offline use.') }, updatefound () { console.log('New content is downloading.') }, updated () { console.log('New content is available; please refresh.') }, offline () { console.log('No internet connection found. App is running in offline mode.') }, error (error) { console.error('Error during service worker registration:', error) } }) }
4.編寫service-worker.js
* 設置緩存前綴和后綴,一般用項目名做前綴,版本號作后綴
// 設置相應緩存的名字的前綴和后綴 workbox.core.setCacheNameDetails({ prefix: 'pdf-image-vue-cache', suffix: 'v1.0.0', }) // 讓我們的service worker盡快的得到更新和獲取頁面的控制權 workbox.core.skipWaiting(); workbox.core.clientsClaim(); /* vue-cli3.0通過workbox-webpack-plagin 來實現相關功能,我們需要加入 * 以下語句來獲取預緩存列表和預緩存他們,也就是打包項目后生產的html,js,css等\* 靜態文件 */ workbox.precaching.precacheAndRoute(self.__precacheManifest || []); // 緩存web的css資源 workbox.routing.registerRoute( // Cache CSS files /.*\.css/, // 使用緩存,但盡快在后台更新 workbox.strategies.staleWhileRevalidate({ // 使用自定義緩存名稱 cacheName: 'css-cache' }) ); // 緩存web的js資源 workbox.routing.registerRoute( // 緩存JS文件 /.*\.js/, // 使用緩存,但盡快在后台更新 workbox.strategies.staleWhileRevalidate({ // 使用自定義緩存名稱 cacheName: 'js-cache' }) ); // 緩存web的圖片資源 workbox.routing.registerRoute( /\.(?:png|gif|jpg|jpeg|svg)$/, workbox.strategies.staleWhileRevalidate({ cacheName: 'images', plugins: [ new workbox.expiration.Plugin({ maxEntries: 60, maxAgeSeconds: 1 * 24 * 60 * 60 // 設置緩存有效期為30天 }) ] }) ); // 我們很多資源在其他域名上,比如cdn、oss等,這里做單獨處理,需要支持跨域 workbox.routing.registerRoute( /^https:\/\/cdn\.my\.com\/.*\.(jpe?g|png|gif|svg)/, workbox.strategies.staleWhileRevalidate({ cacheName: 'cdn-images', plugins: [ new workbox.expiration.Plugin({ maxEntries: 60, maxAgeSeconds: 1 * 24 * 60 * 60 // 設置緩存有效期為5天 }) ], fetchOptions: { credentials: 'include' // 支持跨域 } }) ); // 緩存get api請求的數據 // workbox.routing.registerRoute( // new RegExp('https://m.my.com/api'), // workbox.strategies.networkFirst({ // cacheName: 'api' // }) // ); // 緩存post api請求的數據 // const bgSyncPlugin = new workbox.backgroundSync.Plugin('apiQueue', { // maxRetentionTime: 1 * 60 // }); // workbox.routing.registerRoute( // /.*\/api\/.*/, // new workbox.strategies.NetworkOnly({ // plugins: [bgSyncPlugin] // }), // 'POST' // );
* 配置service work的更新激活策略
// 讓我們的service worker盡快的得到更新和獲取頁面的控制權 workbox.skipWaiting(); workbox.clientsClaim();
* 設置預加載
/\* \* vue-cli3.0通過workbox-webpack-plagin 來實現相關功能,我們需要加入 \* 以下語句來獲取預緩存列表和預緩存他們,也就是打包項目后生產的html,js,css等\* 靜態文件 \*/ workbox.precaching.precacheAndRoute(self.\_\_precacheManifest || \[\]);
* 設置資源緩存策略,workbox主要提供以下幾種緩存策略

cacheFirst:如果請求命中緩存,則將使用緩存的響應來完成請求,不會使用網絡。 如果沒有命中緩存,將通過網絡請求來獲取數據,並且將數據緩存,以便下次直接從緩存獲取數據。該模式可以為前端提供快速響應的同時,減輕服務器壓力。但是數據的時效性就需要開發者通過設置緩存過期時間或更改service-work.js里面的修訂標識來完成緩存文件的更新
networkFirst:優先從網絡獲取最新數據。 如果成功,它會將數據放入緩存。如果網絡無法返回響應,則將使用緩存數據。
networkOnly:只使用網絡請求數據
cacheOnly:只使用緩存數據
我采用的緩存策略如下
// 設置相應緩存的名字的前綴和后綴 workbox.core.setCacheNameDetails({ prefix: 'pdf-image-vue-cache', suffix: 'v1.0.0', }) // 緩存web的css資源 workbox.routing.registerRoute( // Cache CSS files /.*\.css/, // 使用緩存,但盡快在后台更新 workbox.strategies.staleWhileRevalidate({ // 使用自定義緩存名稱 cacheName: 'css-cache' }) ); // 緩存web的js資源 workbox.routing.registerRoute( // 緩存JS文件 /.*\.js/, // 使用緩存,但盡快在后台更新 workbox.strategies.staleWhileRevalidate({ // 使用自定義緩存名稱 cacheName: 'js-cache' }) ); // 緩存web的圖片資源 workbox.routing.registerRoute( /\.(?:png|gif|jpg|jpeg|svg)$/, workbox.strategies.staleWhileRevalidate({ cacheName: 'images', plugins: [ new workbox.expiration.Plugin({ maxEntries: 60, maxAgeSeconds: 1 * 24 * 60 * 60 // 設置緩存有效期為30天 }) ] }) ); // 我們很多資源在其他域名上,比如cdn、oss等,這里做單獨處理,需要支持跨域 workbox.routing.registerRoute( /^https:\/\/cdn\.my\.com\/.*\.(jpe?g|png|gif|svg)/, workbox.strategies.staleWhileRevalidate({ cacheName: 'cdn-images', plugins: [ new workbox.expiration.Plugin({ maxEntries: 60, maxAgeSeconds: 1 * 24 * 60 * 60 // 設置緩存有效期為5天 }) ], fetchOptions: { credentials: 'include' // 支持跨域 } }) ); // 緩存get api請求的數據 // workbox.routing.registerRoute( // new RegExp('https://m.my.com/api'), // workbox.strategies.networkFirst({ // cacheName: 'api' // }) // ); // 緩存post api請求的數據 // const bgSyncPlugin = new workbox.backgroundSync.Plugin('apiQueue', { // maxRetentionTime: 1 * 60 // }); // workbox.routing.registerRoute( // /.*\/api\/.*/, // new workbox.strategies.NetworkOnly({ // plugins: [bgSyncPlugin] // }), // 'POST' // );
5.修改vue.config.js
module.exports={pwa: { name: 'easy-front-vue-cli3', themeColor: '#4DBA87', msTileColor: '#000000', appleMobileWebAppCapable: 'yes', appleMobileWebAppStatusBarStyle: 'black', // configure the workbox plugin (GenerateSW or InjectManifest) workboxPluginMode: 'InjectManifest', workboxOptions: { // swSrc is required in InjectManifest mode. swSrc: './src/service-worker.js', // ...other Workbox options... } }}
*workboxPluginMode:workbox的模式,GenerateSW使用默認模式,InjectManifest使用自定義模式
*workboxOptions.swSrc: 指定service-worker.js所在位置(項目使用相對路徑)
6.在目錄public下添加manifest.json
manifest.json包含了快捷方式的名稱、圖標、入口路徑等配置。 如果不需要快捷方式,也可以不創建
{ "name": "pdf-image-vue", "short_name": "pdf-image-vue", "icons": [ { "src": "/img/icons/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/img/icons/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "start_url": "/pdf", "display": "standalone", "background_color": "#000000", "theme_color": "#4DBA87" }
如果覺得對你有幫助,歡迎打賞