【发布时间】:2019-02-25 13:49:18
【问题描述】:
我有一个带有公共堆栈的简单应用程序:
- 后端服务器 (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],
},
});
在我的组件的已创建生命周期挂钩中调用该操作:
// 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',
}),
};
我上面写的代码有问题,我实际上在我的模板中使用了计算值“参与”:
<BaseTitleGroup
:subtitle="participation.attributes.name"
title="Investissements"
/>
当然,因为我在组件呈现自身时使用了参与,所以我从 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>
我认为有几种解决方案可以解决这个问题,我想知道哪一种是最佳做法,或者是否有更好的一种。
- 第一个解决方案是在我的模板中放置一个 v-if 属性,以防止元素在等待数据时呈现
- Con : 渲染偏移量(元素在数据存在时开始渲染)?
- 缺点:我必须为我的应用程序中处理异步数据的每个组件都这样做,直觉上我更愿意在其他地方处理这个问题(也许是商店?)。
- 渲染元素并将假数据放入存储中,例如“正在加载...”
- 缺点:当文本从加载切换到真实文本时,用户在加载页面时看到的小故障很难看。
- 缺点:当我的应用程序扩展时,我的商店的空版本写起来会很痛苦,而且超级大
- 更改 getter 以返回初始空数据,而不是 store
- 缺点:Getter 变得更加复杂
- 缺点:不需要 getter 的数据怎么办(也许它们可以直接从状态访问)
- 还有别的吗?
我正在寻找处理这种模式的最佳解决方案,即使它是上述之一,我只是不确定哪一个是最好的。非常感谢阅读!另外,我使用 vue 框架,但我认为它更多是关于现代 javascript 框架处理异步数据和渲染的一般问题。
抱歉,帖子太长了,这是一个土豆! (糟糕,不在 9gag 上;))
【问题讨论】:
-
在我看来,第三种方法是最干净的,因为使用 getter 永远不会导致错误。我会做类似的事情: state.investment.included[0] || ""
标签: javascript vue.js vuejs2 vuex