【问题标题】:Inform App.vue a Service-Worker Event is Being Called通知 App.vue 正在调用 Service-Worker 事件
【发布时间】:2018-12-08 06:47:05
【问题描述】:

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

但在我的 Vue.js 应用程序中,由于 service-worker 代码在 main.js 中执行,并且我的小吃店横幅内置在我的 App.vue 组件中,我不确定如何触发我的 showRefreshUI() 方法一旦调用了 service-worker 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>

如果我不能从main.js 调用showRefreshUI() 方法,我如何将updated() 事件中的某些内容传递给App.vuemounted() 生命周期挂钩来完成相同的基本操作?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我不确定,但我认为您可以为此使用 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) 当 service worker 更新时调度自定义事件 ..

      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>
      

      【讨论】:

      • 好吧,经过一番反复试验,这个解决方案效果很好!谢谢你。由于某种原因,将事件构造函数放在main.js 中时,我无法让它工作。我不断收到 updateEvent is not defined 错误。所以我将该代码移至register-service-worker,它工作得很好。我发现我还需要在App.vue 中的updated 事件中返回的registration 对象,因此我也利用了自定义事件语法中提供的detail 属性。这么光滑。再次感谢。
      • @Doug 那是我的错误。我想你也可以直接做document.dispatchEvent(new Event('SWUpdated'),因为你只使用它一次。无论如何,很高兴事情最终为你解决了:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      相关资源
      最近更新 更多