Inform App.vue вызывается событие Service-Worker - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть проект, созданный с использованием Vue CLI 3 с включенным плагином Vue для PWA.Я хотел бы отобразить баннер, предлагающий пользователю щелкнуть ссылку «Обновить» в приложении, как описано здесь в разделе «Подход № 3».

Но в моем Vue.jsприложение, потому что код сервисного работника выполняется в main.js, а мой баннер снэк-бара встроен в мой компонент App.vue, я не уверен, как вызвать мой метод showRefreshUI() после события сервис-работник updated()был вызван.

main.js (соответствующая часть)

import Vue from 'vue';
import App from './App';
import './registerServiceWorker';

new Vue({
  router,
  render: h => h(App),
}).$mount('#app');

register-service-worker (соответствующая часть)

import { register } from 'register-service-worker';

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    updated (registration) {
      console.log('New content is available; please refresh.');
      // I'd like to call App.vue's showRefreshUI() method from here.
    },
  });
}

App.vue (соответствующая часть)

<script>
export default {
  name: 'App',
  mounted () {
    // Alternatively, I'd like to call this.showRefreshUI() from here
    // when the service worker's updated() method is called.
  },

  methods: {
    showRefreshUI () {
      // My code to show the refresh UI banner/snackbar goes here.
    },
  },
};
</script>

Если я не могу вызвать метод showRefreshUI() из main.js, как я могу передать что-то из события updated() в mounted() хук жизненного цикла App.vue, чтобы выполнить то же самое?основная вещь?

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Окончательным рабочим решением для меня было оставить main.js нетронутым, и вместо этого:

register-service-worker (соответствующая часть)

import { register } from 'register-service-worker';

const UpdatedEvent = new CustomEvent('swUpdated', { detail: null });

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    updated (registration) {
      console.log('New content is available; please refresh.');
      UpdatedEvent.detail = registration;
      document.dispatchEvent(UpdatedEvent);
    },
  });
}

App.vue (соответствующая часть)

<script>
export default {
  name: 'App',
  data () {
    return {
      registration: null,
    };
  },
  mounted () {
    document.addEventListener('swUpdated', this.showRefreshUI);
  },
  beforeDestroy () {
    document.removeEventListener('swUpdated', this.showRefreshUI);
  },
  methods: {
    showRefreshUI (e) {
      this.registration = e.detail;
      // My code to show the refresh UI banner/snackbar goes here.
    },
  },
};
</script>
0 голосов
/ 08 декабря 2018

Я не уверен, но я думаю, что вы могли бы использовать пользовательское событие для этой цели.Нечто подобное может работать для вас ..

1) Создайте пользовательское событие в вашем main.js ..

main.js

import Vue from 'vue';
import App from './App';
import './registerServiceWorker';

const updateEvent = new Event('SWUpdated');

new Vue({
  router,
  render: h => h(App),
}).$mount('#app');

2) Отправьтенастраиваемое событие при обновлении работника службы ..

register-service-worker

import { register } from 'register-service-worker';

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    updated (registration) {
      console.log('New content is available; please refresh.');
      document.dispatchEvent(updateEvent);
    },
  });
}

3) Присоедините прослушиватель событий к объекту документа в вашей ловушке mounted, которая прослушивает ваше настраиваемое событие,Удалите прослушиватель событий из beforeDestroy hook.

App.vue

<script>
export default {
  name: 'App',
  mounted () {
    document.addEventListener('SWUpdated', this.showRefreshUI);
  },
  beforeDestroy () {
    document.removeEventListener('SWUpdated', this.showRefreshUI);
  },
  methods: {
    showRefreshUI () {
      // My code to show the refresh UI banner/snackbar goes here.
    },
  },
};
</script>
...