【问题标题】:Undefined property error before store gets populated by API call存储被 API 调用填充之前的未定义属性错误
【发布时间】:2023-04-01 17:00:02
【问题描述】:

在我的子组件中,我试图访问存储状态对象(称为 template)的嵌套属性(称为 background_color):

<template>
  <div
    class="btn"
    :style="{ 'background-color': backgroundColor }"
  >
    content
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState({
      backgroundColor: state => state.template.button_branding.secondary_button.background_color
    })
  }
}
</script>

商店是从父视图组件中通过商店操作调用填充的:

created () {
  this.initializeStore()
},

在我的商店中,此操作是这样定义的:

export const actions = {
  initializeStore ({ state, commit }, data) {
    this.$axios.get('path.to.api.endpoint')
      .then((res) => {
        commit('setConfig', res.data) // populates store
      }).catch((error) => {
        console.log(error)
      })
  }
}

我收到此错误:

无法读取未定义的属性“secondary_button”

但我看到我的嵌套属性通过 Vue DevTools 填充在状态中。

我怎样才能避免这个错误?

【问题讨论】:

    标签: vue.js nuxt.js vuex


    【解决方案1】:

    您可以使用可选链接和空值合并来添加默认值,如下所示:

    backgroundColor: state =&gt; state.template?.button_branding?.secondary_button?.background_color ?? 'default_value'

    这应该可以防止调用 API 时出现错误。

    此外,将您的逻辑移动到商店内的getter 中并在那里设置默认值可能会更简洁:

    getters: {
      backgroundColor: state => {
        return state.template?.button_branding?.secondary_button?.background_color ?? 'default_value'`;
      }
    }
    

    这样组件就可以使用mapGetters,并且不需要关心是否使用了默认值。

    【讨论】:

    • 哇,这很好用,谢谢!我从来没有见过这样的事情,我今天肯定学到了一些东西:) 我想知道。我的这个问题看起来非常基本,实际上我怀疑大多数大型 Vue 项目都会遇到它。没有标准或惯用的方法来解决它吗?
    • 在等待 API 调用时使用默认值是 IMO 的标准方法,但有多种方法可以实现这一点。例如,您可以完全实例化您的状态,以便在获取数据之前该属性已经存在 - 具有默认值,但我认为这会不太整洁,因为您在这里处理的是深度嵌套的属性。我已经用进一步的建议更新了我的答案。
    • 是的,你是对的,设置默认值确实很常见。只有当状态非常复杂因此动态填充时才会出现此类问题。无论如何,非常感谢。
    猜你喜欢
    • 2013-03-02
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多