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.

  1. This article source address: github.com/louie-001/v…
  2. For details about how to save the endpoint and use web push messages on the server, see juejin.cn/post/689073…