通知App.vue正在调用Service-Worker事件

时间:2018-12-08 06:47:05

标签: vue.js vuejs2 service-worker progressive-web-apps vue-cli-3

我有一个使用Vue CLI 3创建的项目,其中包括Vue的PWA插件。我想显示一条横幅广告,提示用户单击“方法#3”部分中here中所述的应用内“刷新”链接。

但是在我的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()传递到App.vue的{​​{1}}生命周期钩子完成相同的基本任务?

2 个答案:

答案 0 :(得分:3)

对我来说,最后的可行解决方案是保持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>

答案 1 :(得分:1)

我不确定,但是我认为您可以为此使用custom event。这样的事情可能对您有用..

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钩子中删除事件侦听器。.

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>