У меня есть Vue PWA с ServiceWorker. Когда ServiceWorker (registerServiceWorker. js) импортируется, он проверяет, доступна ли новая версия, и если да, то я хочу предоставить пользователю возможность обновления. Но в этот момент я нахожусь в модуле JavaScript, как я могу добавить всплывающее окно / сообщение + кнопку в документ HTML в этот момент?
В идеале я бы настроил свое сообщение заранее, используя закусочная Vuetify, или что-то подобное в приложении. vue или в навигационной панели. vue, которую я мог бы показать / скрыть на основе глобальной переменной, события или чего-то еще.
Однако есть усложняющий фактор: кнопка должна выполнить js -код на основе параметра ...
main. js (упрощенно):
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import vuetify from './plugins/vuetify'
import './registerServiceWorker'
new Vue({
router,
vuetify,
render: h => h(App)
}).$mount('#app')
Приложение. vue (упрощенно):
<template>
<v-app>
<Navbar/>
<v-content>
<router-view></router-view>
</v-content>
<Footer/>
</v-app>
</template>
<script>
import styles from './app.css'
import Navbar from '@/components/Navbar'
import Footer from '@/components/Footer'
export default {
name: 'App',
components: { Navbar, Footer },
}
</script>
registerServiceWorker. js
function onNewServiceWorker(registration, callback) {
if (registration.waiting) {
// SW is waiting to activate. Can occur if multiple clients open and
// one of the clients is refreshed.
return callback();
}
function listenInstalledStateChange() {
registration.installing.addEventListener('statechange', function(event) {
if (event.target.state === 'installed') {
// A new service worker is available, inform the user
callback();
}
});
};
if (registration.installing) {
return listenInstalledStateChange();
}
// We are currently controlled so a new SW may be found...
// Add a listener in case a new SW is found,
registration.addEventListener('updatefound', listenInstalledStateChange);
}
if (process.env.NODE_ENV === 'production') {
window.addEventListener('load', function() {
var refreshing
// When the user asks to refresh the UI, we'll need to reload the window
navigator.serviceWorker.addEventListener('controllerchange', function(event) {
if (refreshing) return // prevent infinite refresh loop when you use "Update on Reload"
refreshing = true
console.log('Controller loaded')
window.location.reload()
})
navigator.serviceWorker.register(`${process.env.BASE_URL}service-worker.js`,{})
.then(function (registration) {
// Track updates to the Service Worker.
if (!navigator.serviceWorker.controller) {
// The window client isn't currently controlled so it's a new service
// worker that will activate immediately
return
}
registration.update()
onNewServiceWorker(registration, function() {
//showRefreshUI(registration);
console.log('TODO: show update message')
})
});
});
}
Закомментированный showRefreshUI(registration)
вызов - это то, что мне нужно иметь в моем шаблоне Vue, и здесь есть усложняющий фактор, он основан на параметре registration
:
function showRefreshUI(registration) {
var button = document.createElement('button');
button.style.position = 'absolute';
button.style.bottom = '24px';
button.style.left = '24px';
button.textContent = 'This site has updated. Please click here to see changes.';
button.addEventListener('click', function() {
if (!registration.waiting) {
// Just to ensure registration.waiting is available before
// calling postMessage()
return;
}
button.disabled = true;
registration.waiting.postMessage('skipWaiting');
});
document.body.appendChild(button);
};
К вашему сведению, регистрация ServiceWorker основана на:
Я только начинаю работать с Vue и PWA. Пожалуйста, потерпите меня здесь; -)