如何使用Vuex/Vue处理异步数据检索

Uel*_*elb 5 javascript vue.js vuex vuejs2

我有一个带有共同堆栈的简单应用程序:

  • 后端服务器(Rails)
  • 前端应用程序(Vue)
  • 数据库(PG)

Vue应用程序使用Vuex存储库的操作从后端获取数据,如下所示:

// store/store.js
import Vue from 'vue';
import Vuex from 'vuex';
import * as MutationTypes from '@/store/mutation-types';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    investment: {},
  },
  mutations: {
    [MutationTypes.SET_INVESTMENT_SHOW](state, investment) {
      state.investment = investment;
    },
  },
  actions: {
    fetchInvestment({ commit }, id) {
      InvestmentsApi.get(id).then((response) => {
        commit(MutationTypes.SET_INVESTMENT_SHOW, response.data);
      });
    },
  },
  getters: {
    participation: state =>
      state.investment.included[0],
  },
});
Run Code Online (Sandbox Code Playgroud)

在我的组件的创建生命周期钩子中调用该操作,如下所示:

// components/Investment.vue

import { mapActions, mapGetters } from 'vuex';
export default {
  name: 'Investment',
  computed: {
    ...mapState(['investment']),
    ...mapGetters(['participation']),
  },
  created() {
    this.fetchData(this.$route.params.id);
  },
  methods: mapActions({
    fetchData: 'fetchInvestment',
  }),
};
Run Code Online (Sandbox Code Playgroud)

我在上面编写的代码中存在一个问题,我实际上在我的模板中使用计算值'参与',如下所示:

<BaseTitleGroup
  :subtitle="participation.attributes.name"
  title="Investissements"
/>
Run Code Online (Sandbox Code Playgroud)

当然,因为我在组件渲染时使用了参与,所以我从getter方法得到了这个错误:

Error in render: "TypeError: Cannot read property '0' of undefined"

found in

---> <InvestmentSummary> at src/views/InvestmentSummary.vue
       <App> at src/App.vue
         <Root>
Run Code Online (Sandbox Code Playgroud)

我认为有几种解决方案可以解决这个问题,我想知道哪一个是最佳实践,或者是否有更好的实践.

  1. 第一个解决方案是在我的模板中放置一个v-if属性,以防止在等待数据时呈现元素
    • Con:渲染偏移(当数据存在时,元素开始渲染)?
    • Con:我必须为我的应用程序中处理异步数据的每个组件执行此操作,直觉上我更愿意在其他地方处理此问题(可能是商店?).
  2. 渲染元素并将虚假数据放入商店,例如"正在加载..."
    • Con:当文本从加载切换到真实文本时,用户在加载页面时看到的小故障很难看.
    • Con:当我的应用扩展时,我的商店的空版本会很难写,超级大
  3. 更改getter以返回初始空数据,而不是商店
    • Con:Getters变得更复杂
    • 骗:那些不需要吸气剂的数据(也许可以从州直接获取)
  4. 别的什么?

我正在寻找处理这种模式的最佳解决方案,即使它是上述之一,我只是不确定哪一种是最好的.非常感谢阅读!另外,我使用vue框架,但我认为这是关于现代javascript框架处理异步数据和渲染的一般问题.

对不起,很长的帖子,这是一个土豆!(糟糕,不是9gag;))

dzi*_*raf 2

我认为没有最好的解决方案,只需选择一个并在各处使用它,而不是混合使用它们。

v-if但是,如果您想从嵌套属性渲染数据,可能会更好 -v-if="object.some.nested.property v-for="el in object.some.nested.property"可以工作,但预定义object = {}不会(它会抛出未定义的错误some,并且您正在尝试访问它)。

我不会像您的示例中那样放置任何虚假数据,但您可以使用 ES6来定义默认对象并将它们设置为默认值。只要您的类对象具有正确的结构(并且它在语法上也是透明且易于理解),这也可以解决上述预定义问题。

至于第三个选项 - 向 getter 提供空数据不必很复杂 - 只需将 getter 更改为:

getters: {
    participation: state =>
      state.investment.included[0] || new DefaultParticipationObject() // I don't know what's in included array
  },
Run Code Online (Sandbox Code Playgroud)

如果已定义则使用它state.investment.included[0],否则使用默认对象。