如何在Vuex动作完成之前阻止Vue生命周期继续进行? [英] How to stop Vue life cycle from moving on before Vuex actions have completed?

查看:653
本文介绍了如何在Vuex动作完成之前阻止Vue生命周期继续进行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我想在其余应用程序启动之前初始化3个Vuex模块.但是,无论我如何尝试,我执行初始化的Vue实例生命周期挂钩中的代码都会在3个模块完成初始化之前继续执行.

In my application, I want to initialize 3 Vuex modules before the rest of the application starts. However, no matter what I try, the code in the Vue instance life cycle hook in which I perform the initialize, moves on before the 3 modules have completed their initialization.

我在执行初始化的Vuex操作中的代码周围添加了一个承诺,以便我可以(a)等待调用生命周期挂钩中的代码,但这是行不通的.

I have added a promise around the code in the Vuex actions that do the initializing, so that I can (a)wait on those in the calling life cycle hook, but it doesn't work.

我已经看过使用Axios的Vuex示例代码,我必须使我的代码与此相似,但是没有成功.

I have looked at sample Vuex code that uses Axios, and I have to make my code similar to that, but without success.

我尝试使用"Promise.all(...)"在"beforeCreate"生命周期挂钩中进行init调用,但这仍然无法解决.

I tried init call in the "beforeCreate" life cycle hook with "Promise.all(...)", but that still did not fix it.

我的主要Vue实例的代码如下:

The code of my main Vue instance looks like this:

new Vue({
  router,
  store,
  async beforeCreate() {
    await this.$store.dispatch('init')
  },
  render: h => h(App)
}).$mount('#app')

Vuex存储由3个模块组成,所有这些模块都有一个'init'操作.这三个模块中的操作代码都相同.如果下面的代码中有"XXX",则每个模块的调用会稍有不同;

The Vuex store consists of 3 modules, all of which have a 'init' action. The code of action in all 3 modules is the same. Where ever there is "XXX" in the code below, will be a slightly different call for each module;

  init: ({commit, dispatch}) => {
    return new Promise((resolve, reject) => {
      console.log('Start of init of XXX');
      Axios.get(`api/xxx`).then(response => {
        return response.data;
      }, error => {
        console.log('An error occured: ', error);
        reject(error);
      }).then(data => {
        const result = [];
        for (let key in data) {
          result.push(data[key]);
        }

        console.log('The API call resulted in ' + result.length + ' lines of code');

        resolve(result);
        commit('ADD_XXX', result);
      })
    })
  }

我期望的是"beforeCreate"代码继续进行下去,直到3个init动作调用已完全完成(即,直到所有诺言都已兑现)为止.

What I expect is that the "beforeCreate" code waits with moving on until the 3 init action calls have been fully completed (i.e. until all promises have been fulfilled).

我看到的是动作已开始(我在控制台中看到开始初始化..."日志).但是然后我看到一个应用程序组件之一的mounted()函数中的代码开始执行,它不应该执行,因为如果存储尚未完全初始化,它将无法正常工作.

What I see, is that the actions are started (I see the "Start of init..." log in the console). But then I see that code in the mounted() function of one of the applications components is started to execute, which it should not, as it will not work correctly if the store has not been fully initialized.

推荐答案

您不能通过将beforeCreate设置为async来使其暂停.当您按下await时,它似乎在内部被暂停",但从外部角度来看,它只是返回一个承诺. Vue不会注意返回值,因此Promise将被忽略,并且生命周期将继续不间断.您可以做的是在data中添加一些状态,并对其进行处理以达到所需的效果:

You can't pause beforeCreate by making it async. It might appear to be 'paused' internally when you hit the await but from an external perspective it just returns a promise. Vue doesn't take any notice of the return value so the promise will be ignored and the life-cycle will continue uninterrupted. What you can do is add some state into your data and manipulate that to achieve the desired effect:

new Vue({
  router,
  store,
  data () {
    return {
      ready: false
    }
  },
  async beforeCreate() {
    await this.$store.dispatch('init')
    this.ready = true
  },
  render (h) {
     if (this.ready) {
       return h(App)
     }
  }
}).$mount('#app')

顺便说一句,您无需在init中创建新的Promise,只需返回axios创建的链式Promise.

Incidentally, you shouldn't need to create a new promise in init, you can just return the chained promise created by axios.

更新:

这是另一种方法,只是不停地拨打mount.

Here's another way, just holding back on calling mount.

new Vue({
  router,
  store,
  async beforeCreate() {
    await this.$store.dispatch('init')
    this.$mount('#app')
  },
  render: h => h(App)
})

这篇关于如何在Vuex动作完成之前阻止Vue生命周期继续进行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆