如何在调用 vuex 动作时传递对组件的引用

how to pass a reference to a component when calling a vuex action

我对 vue 还很陌生(对 vuex 也很陌生)。我想将一些 axios api 调用移动到我的 Vuex 商店中。我知道有例如:

  actions:{
    LOAD_USER: function ({ commit }) {
      axios.get('/arc/api/v1/me', {dataType: 'json'})
      .then((response )=> {
        commit('SET_USER', { user: response.data.user })
      })
      .catch(function (error) {
        console.log(error.message);
      });

并通过以下方式在我的调用组件中调用它:

  this.$store.dispatch('LOAD_USER')

这是有效的。我的问题是我需要将调用组件中的一些变量设置为 false 或终止进度条。这是我之前在调用组件中使用的内容:

  this.loading = true
  this.$Progress.start()
  axios.get('/arc/api/v1/me', {dataType: 'json'})
  .then((response )=> {
    this.$Progress.finish()
    this.loading = false
    this.$store.state.user = response.data.user;
    this.user = this.$store.state.user
  })
  .catch(function (error) {
    this.$Progress.fail()
    console.log(error.message);
  });

如何将这些加载行为集成到我的 vuex 操作中?我将如何通过此调用传递对我的组件的引用:

  this.$store.dispatch('LOAD_USER')

或者有更好的解决办法吗?

好吧,你总是可以使用 Store.dispatch() 的第二个参数将任何负载传递到相应的操作中:

this.$store.dispatch('LOAD_USER', this); // passing reference as payload

...但我强烈建议不要这样做。相反,我宁愿让 VueX 处理整个状态(包括 'loading' 标志等)。

在这种情况下,存储一个 action - LOAD_USER, based on asynchronous API request - would commit two mutations:第一个在请求开始时设置 loading 标志,第二个将其重置回 false - 和加载用户数据。例如:

LOAD_USER: function ({ commit }) {
  commit('LOADING_STARTED'); // sets loading to true
  axios.get('/arc/api/v1/me', {dataType: 'json'})
  .then(response => {
    commit('LOADING_COMPLETE'); // resets loading flag
    commit('SET_USER', { user: response.data.user });
  })
  .catch(error => {
    commit('LOADING_ERROR', { error }); // resets loading
    console.log(error.message);
  });

这种方法除了其他优点外,还可以在您的请求逻辑变得更加复杂时大大简化事情 - 包括错误处理、重试等。

行动可以return承诺https://vuex.vuejs.org/en/actions.html 我想你想要做的是在你调用你的动作时激活加载,并在承诺被解决或拒绝时停止加载。

// Action which returns a promise.
actions: {
  LOAD_USER ({ commit }) {
    return new Promise((resolve, reject) => {
      axios.get('/arc/api/v1/me', {dataType: 'json'})
        .then((response )=> {
          commit('SET_USER', { user: response.data.user })
          resolve()
        })
        .catch(function (error) {
          console.log(error.message);
          reject(error);
        });
    })
  }
}

// Update loading when the action is resolved.
this.loading = true;
store.dispatch('LOAD_USER').then(() => {
  this.loading = false;
})
.catch(function(error) {
  // When the promise is rejected
  console.log(error);
  this.loading = false;
});

如果您无法使用上述方法实现您的目标,您可以将加载布尔值添加到您的 vuex 存储并将其导入到您的组件中。比修改你的动作中的加载布尔值(使用突变)让视图更新。

注意:我不会传递对您的操作的引用。虽然这是可能的,但可能有更好的解决方案来解决您的问题。尽可能在组件中保留视图逻辑。