根据 Vue 中的数据变化切换对象(使用 Vuex)

Posted

技术标签:

【中文标题】根据 Vue 中的数据变化切换对象(使用 Vuex)【英文标题】:Switching out object based on data changing in Vue (with Vuex) 【发布时间】:2020-06-22 18:17:48 【问题描述】:

我正在尝试根据在组件页面顶部的选项卡列表中单击的内容来切换组件中的数据。数据来自 Vuex 数据存储。通过测试 Vuex 数据存储,一切似乎都运行良好。我的数据存储中有虚拟数据,在我的 Vue Chrome 开发工具插件中似乎没问题。

当我在下面构建我的组件并尝试加载页面时,控制台正在抱怨Cannot read property 'amount' of undefined。我假设这是因为数据是在计算属性进入 Vue 之前加载的。

我觉得我想多了,但我的目标是在单击我的一个选项卡时切换显示的数据。我可以为每个标签创建一个组件,然后收工,但我觉得这会非常重复。


我的尝试

-尝试将数据的currentObj: this.obj1 替换为currentObj: 。同样的错误。

-尝试将currentObj 数据属性移动到计算属性。当我这样做时,页面会加载,但我仍然收到相同的错误,当我单击选项卡时,我的数据没有更新。


知道如何在我的组件中切换出currentObj 中的数据吗?

<template>
  <div>
    <ul class="tabs">
      <li class="tab-title" v-on:click="tabSelection = 'tab1'">Tab 1</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab2'">Tab 2</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab3'">Tab 3</li>
    </ul>
    <div> currentObj.amount </div>
  </div>
<template>

<script>
export default 
  data: function() 
    return 
      tabSelection: 'tab1',
      currentObj: this.obj1
    
  ,
  watch: 
    tabSelection: function(oldTabSelection, newTabSelection) 
      switch (newTabSelection) 
        case 'tab1':
          this.currentObj = this.obj1;
          break;
        case 'tab2':
          this.currentObj = this.obj2;
          break;
        case 'tab3':
          this.currentObj = this.obj3;
          break;
      
    
  ,
  computed: 
    obj1: function() 
      return this.$store.getters.obj1;
    ,
    obj2: function() 
      return this.$store.getters.obj2;
    ,
    obj3: function() 
      return this.$store.getters.obj3;
    
  

</script>

【问题讨论】:

【参考方案1】:

问题是currentObj 在某些时候是未定义的,这不是预期的。可以像另一个答案显示的那样处理该症状,如果商店中可能缺少obj1 等,它会很有用。只有在单击选项卡时未定义 obj1 等时才会发生这种情况:

尝试将数据的 currentObj: this.obj1 替换为 currentObj: 。同样的错误。

即使 obj1 等在存储中可用,obj1 计算属性在 data 中也不可用,因为此时尚未创建组件实例,因为它需要创建数据。 databeforeCreatecreated 钩子之间运行。

一种解决方法是调用 getter:

currentObj: this.$options.computed.getNumbers.call(this)

当然,如果计算属性使用其他不可用的东西,这可能会导致问题。更正确的解决方法是明确指定初始数据:

currentObj: this.$store.getters.obj1

正确的解决方案是以不成问题的方式设计组件。 tabSelection 不需要观察者,currentObj 应该是计算属性而不是数据,因为它是从tabSelection计算

  computed: 
    currentObj() 
      let obj;
      switch (this.tabSelection) 
        case 'tab1':
          obj = this.obj1;
          break;
        case 'tab2':
          obj = this.obj2;
          break;
        case 'tab3':
          obj = this.obj3;
          break;
      
      return obj ||  amount: 'No amount'  // in case missing objs are expected
    ,
    ...

【讨论】:

【参考方案2】:

我建议您更改模板。尝试使用安全导航:

<template>
  <div>
    ...
    <div> currentObj && currentObj.amount </div>
  </div>
<template>

或者

<template>
  <div>
    ...
    <div v-if="currentObj"> currentObj.amount </div>
  </div>
<template>

【讨论】:

这个答案解决了你的问题吗?请接受此答案,这将对其他人有所帮助。 How to accept an answer? - Why accept an answer?

以上是关于根据 Vue 中的数据变化切换对象(使用 Vuex)的主要内容,如果未能解决你的问题,请参考以下文章

vue监听一个对象属性变化为啥打印不出来对象

vue 监听对象属性的变化

使用vuex中的store存储数据

在vue中使用resize事件监听浏览器窗口的变化

Vuex使用总结

Vuetify 在明暗主题之间切换(使用 vuex)