PWA (Progressive Web Apps) enables Web applications to have user experiences similar to native applications, such as running offline, adding to the home screen, and messaging notifications (more on that). This paper introduces the use of @vue/ CLI-plugin-pWA plug-in in VUE project to realize message notification and refresh VUE components.
Create the VUE project and install the PWA plug-in
The ue runs the following command to create the vue-pWA-Notification project:
vue create vue-pwa-notification
Copy the code
Run the following command to install the PWA plug-in:
cd vue-pwa-notification
vue add @vue/pwa
Copy the code
Engineering structure after installation:
. ├ ─ ─ Babel. Config. Js ├ ─ ─ package. The json ├ ─ ─ package - lock. Json ├ ─ ─ public │ ├ ─ ─ the favicon. Ico │ ├ ─ ─ img │ │ └ ─ ─ the ICONS │ ├ ─ ─ │ ├─ ├─ trash ├─ │ ├─ trash ├─ │ ├─ trash ├─ │ ├─ trash ├── ├── registerServiceworker.js helloWorld.vue ├─ main.js ├─ registerServiceworker.jsCopy the code
Install AXIOS and implement API client
Install axios:
npm i axios
Copy the code
SRC create the plugins directory and create axios.js under the plugins directory:
// plugins/axios.js
import Axios from "axios";
const axios = Axios.create({
// Environment configuration should be used in actual development
baseURL: 'http://192.168.3.90:3000'.timeout: 10 * 1000.withCredentials: false
})
/** * Request interceptor */
axios.interceptors.request.use(config= > {
config.headers.Authorization = sessionStorage.getItem('access_token')
return config
}, error= > {
return Promise.reject(error)
})
/** * response interceptor */
axios.interceptors.response.use(response= > {
return response
}, error= > {
// Response error
return Promise.reject(error)
})
export default axios
Copy the code
Modify registerServiceWorker. Js
When the service worker is ready, subscribe to the message service and submit the subscribe to the server to save:
// registerServiceWorker.js
import {register} from 'register-service-worker'
import axios from "@/plugins/axios";
/ / the public key
const publicKey = 'BO_sjITRaeBOaC5UDMb6L3_h64FMRozOAgct02jsKcfjvM6SuKcJjQTMXBBGM5H3xhT1u-Oz11_Gi1yC8RDsin4'
if (process.env.NODE_ENV === 'production') {
register('./sw.js', {
// Service worker ready
ready(registration) {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
// Subscribe to the Web push service and submit it to the server for saving
const convertedVapidKey = urlBase64ToUint8Array(publicKey);
const subscribeOption = {
userVisibleOnly: true.applicationServerKey: convertedVapidKey,
}
registration.pushManager.subscribe(subscribeOption).then(endpoint= > {
/ / submit the endpoint
axios.post('endpoint', endpoint).then(res= > {
console.log('save push endpoint result, ' + JSON.stringify(res))
})
})
},
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)
}
})
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g.'+')
.replace(/_/g.'/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
Copy the code
The server saves the endpoint, obtains the endpoint to be notified according to specific conditions in the push message, and sendNotification.
Pwa vue. Config. Js configuration
module.exports = {
publicPath: '/'.pwa: {
name: 'notification'.themeColor: '#1976D2'.msTileColor: '#FFFFFF'.workboxPluginMode: 'InjectManifest'.workboxOptions: {
swSrc: 'src/sw.js'}}}Copy the code
SRC create sw.js
The service worker registers the push event listener
self.addEventListener('push'.evt= > {
const message = evt.data.json()
// Display notifications
self.registration.showNotification(message.title, {
body: message.content
})
})
Copy the code
The application obtains notification permissions on first access, as follows:
Call the server to send messages, and terminal executes:
The curl -x POST http://192.168.3.90:3000/message - b '{" title ":" system notification ", "content" : "nice, this is a notification from web-push"}' -H "Content-Type: application/json"Copy the code
Message notification:
Web Push updates VUE DATA
After service Woker receives the notification of Push from the server, when we click on the notification, the message content is displayed in the VUE component.
Register notification click event in sw.js:
self.addEventListener('notificationclick'.evt= > {
evt.notification.close()
/ / for the client
evt.waitUntil(self.clients.matchAll({ type: 'window' }).then(clients= > {
clients.forEach(client= > {
// postMessage sends information to the interface
client.postMessage(evt.notification.body)
})
}))
})
Copy the code
Register message listener in app.vue:
// App.vue
mounted() {
navigator.serviceWorker.addEventListener('message'.evt= > {
this.response = evt.data
})
}
Copy the code
The vue project needs to be built and deployed, because the @vue/cli-plugin-pwa plug-in only runs in the production environment, because if the service worker is enabled in the dev environment, local changes cannot be used because of caching resources.
- This article source address: github.com/louie-001/v…
- For details about how to save the endpoint and use web push messages on the server, see juejin.cn/post/689073…