在 vuejs/vuex 中计算和创建道具的顺序

Order of Props, Computed, and Created in vuejs/vuex

我对使用 vue 和 vuex 计算和创建道具的正确顺序有一些疑问。

我有以下代码

<script>
  import { mapGetters } from 'vuex'

  export default {
    data () {
      return {}
    },
    props: ['id'],
    methods: {
    },
    computed: {
      ...mapGetters({
        semestre: 'semestre/show/item'
      }),
      titre: function () {
        return this.semestre.nom
      }
    },
    created () {
      this.$store.dispatch('semestre/show/retrieve', parseInt(this.id))
    }
  }
</script>

但是我在计算滴定度时遇到一个错误,它操作了一个未定义的变量 "semestre"。

好像computed是在created之前执行的。所以如果我尝试使用 beforeCreate 代替 Created,它不起作用,因为 props 不存在。

所以我觉得

beforeCreate => Props => Computed => Created ?

但是我怎样才能正确执行我的代码呢?我需要在 props 中获取一个值,将这个值传递给 vuex,然后操作 VueX 的结果。 也许,我不明白vue/vueX的逻辑。

谢谢

大卫

如果您的计算在视图中使用,那么是的,它将在提供 semestre 之前进行计算,因为看起来您的 vuex 操作是异步的。如果它是异步的,您的 created 函数将在操作完成之前完成执行。因此,getter 'semestre/show/item' 将始终 return 一个未定义的值,直到 'semestre/show/retrieve' 操作完全完成,即 而不是 将在 created 完成执行之前。

要处理这个问题,您必须编写组件,以便它们处理值的异步加载。您基本上必须编写您的组件,以便它处理尚未加载的情况,并处理已加载的情况。我建议您更改您的计算,以便它处理未定义或空值:

titre: function () {
    return this.semestre && this.semestre.nom;
    //or if you want to provide a default value
    return (this.semestre && this.semestre.nom) || '??';
}

一种更强大的解决方案是通过跟踪您的操作是否已完成向用户提供正在加载值的反馈。

<template>
    <div v-if="isLoading">Content is load (you could display a spinner)</div>
    <div v-else>
        Display your semestre content here:
        {{titre}}
    </div>
</template>
<script>
  import { mapGetters } from 'vuex'

  export default {
    data () {
      return {
          isLoading: false,
      };
    },
    props: ['id'],
    computed: {
      ...mapGetters({
        semestre: 'semestre/show/item'
      }),
      titre: function () {
        return this.semestre.nom
      }
    },
    async created () {
      this.isLoading = true;
      await this.$store.dispatch('semestre/show/retrieve', parseInt(this.id))
      this.isLoading = false;
    }
  }
</script>

如果您无法使用 async/await 关键字,您可以执行以下操作:

created () {
    this.isLoading = true;
    this.$store.dispatch('semestre/show/retrieve', parseInt(this.id))
        .then(() => {
            this.isLoading = false;
        });
}