新项目直接在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. ' + '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主要提供以下几种缓存策略
![](https://img2020.cnblogs.com/blog/1176808/202103/1176808-20210315151745032-796811251.png)
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" }
如果觉得对你有帮助,欢迎打赏