Cannot access property of JSON in VueJS using a loop index.

huangapple go评论68阅读模式
英文:

Cannot access property of JSON in VueJS using a loop index

问题

以下是您要翻译的内容:

我的VueJS运行应用程序显示来自Strava的活动数据,按周分组,为期20周。我遇到的问题是,来自我的API的对象出现了,但我无法访问每个属性。

以下是来自SFC的相关摘录。

数据

weekly_total_data将随着周数的增加而增长

data() {
    return {
        activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
        weekly_total_data:
           [{"week_number":3,"total_distance":39877.6,"total_moving_time":11841},
            {"week_number":2,"total_distance":58596.4,"total_moving_time":18719},     
            {"week_number":1,"total_distance":41347.5,"total_moving_time":12796}]
    }
}

函数

访问数据

matchWeeklyTotals(){
    var x = this.weekly_total_data
    console.log(x)
    return x
  }
},

模板

循环遍历周数,为每周获取一个索引,然后使用该索引显示该周的适当数据

<div v-for="(week, week_index) in this.activity_weeks" v-bind:value="week._id">
   <div class="container max-w-xl mx-auto">
       <h2 class="text-2xl">第{{week}}周:{{ (matchWeeklyTotals()[week_index])}}</h2>
   </div>
</div>

目前,我可以显示对象,但是当我执行matchWeeklyTotals()[week_index][total_distance]等操作时,它会失败。
我还尝试过JSON.parse的各种变体。

感谢帮助访问total_distancetotal_moving_time

英文:

My VueJS running app displays activity data from Strava, grouped together by week, over a 20-week period. The difficulty that I'm having is that the object from my API appears, but I cannot access each property.

These are the relevant excerpts from the SFC.

DATA

weekly_total_data will grow as the weeks progress

data() {
        {
            return {
            activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
            weekly_total_data:
               [{&quot;week_number&quot;:3,&quot;total_distance&quot;:39877.6,&quot;total_moving_time&quot;:11841},
                {&quot;week_number&quot;:2,&quot;total_distance&quot;:58596.4,&quot;total_moving_time&quot;:18719},     
                {&quot;week_number&quot;:1,&quot;total_distance&quot;:41347.5,&quot;total_moving_time&quot;:12796}]
            }
        }
    }

FUNCTION

Acccessing the data

    matchWeeklyTotals(){
        var x = this.weekly_total_data
        console.log(x)
        return x
      }
    },

TEMPLATE

Looping through the weeks, getting an index for each week, and then using that to display the appropriate data for the week

&lt;div v-for=&quot;(week, week_index) in this.activity_weeks&quot; v-bind:value=&quot;week._id&quot;&gt;
   &lt;div class=&quot;container max-w-xl mx-auto&quot;&gt;
       &lt;h2 class=&quot;text-2xl&quot;&gt;Week {{week}}: {{ (matchWeeklyTotals()[week_index])}}&lt;/h2&gt;
   &lt;/div&gt;
&lt;/div&gt;

As it stands, I can display the object, but when I do matchWeeklyTotals()[week_index][total_distance], as an example, it fails.
I have also tried variations of JSON.parse.

Any help to access the total_distance and total_moving_time appreciated.

答案1

得分: 1

以下是翻译好的部分:

以下的代码正在运行。

我正在过滤 weekly_total_data 来检查 activity_weeks 是否存在于 weekly_total_data => week_number

英文:

The following code is working.

I'm filtering weekly_total_data to check if the activity_weeks exists in weekly_total_data => week_number

&lt;script setup&gt;
const activity_weeks = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

const weekly_total_data = [
  {&quot;week_number&quot;:3,&quot;total_distance&quot;:39877.6,&quot;total_moving_time&quot;:11841},
  {&quot;week_number&quot;:2,&quot;total_distance&quot;:58596.4,&quot;total_moving_time&quot;:18719},
  {&quot;week_number&quot;:1,&quot;total_distance&quot;:41347.5,&quot;total_moving_time&quot;:12796}
]

const matchWeeklyTotals = () =&gt; {
  var x = weekly_total_data
  console.log(x)
  return x
}

&lt;/script&gt;

&lt;template&gt;
  &lt;div v-for=&quot;week in weekly_total_data.filter(x =&gt; x.week_number in activity_weeks)&quot;&gt;
     &lt;div class=&quot;container max-w-xl mx-auto&quot;&gt;
         &lt;h2 class=&quot;text-2xl&quot;&gt;Week {{week.week_number}}: {{ week.total_distance }}&lt;/h2&gt;
     &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

答案2

得分: 1

如果我理解你正确的话,你可以使用 [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining):

```js
const app = Vue.createApp({
  data() {
    return {
      activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
      weekly_total_data: [
        {"week_number":3,"total_distance":39877.6,"total_moving_time":11841},
        {"week_number":2,"total_distance":58596.4,"total_moving_time":18719},     
        {"week_number":1,"total_distance":41347.5,"total_moving_time":12796}
      ]
    }
  },
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <div v-for="(week, week_index) in activity_weeks" v-bind:value="week._id">
    <div class="container max-w-xl mx-auto">
      <h2 class="text-2xl">Week {{ week }}:</h2>
      <p>{{ weekly_total_data[week_index]?.total_distance }}</p>
      <p>{{ weekly_total_data[week_index]?.total_moving_time }}</p>
    </div>
  </div>
</div>

<details>
<summary>英文:</summary>

If I understood You correctly, You can use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining):

&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-js --&gt;

    const app = Vue.createApp({
      data() {
        return {
          activity_weeks: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
          weekly_total_data: [
            {&quot;week_number&quot;:3,&quot;total_distance&quot;:39877.6,&quot;total_moving_time&quot;:11841},
            {&quot;week_number&quot;:2,&quot;total_distance&quot;:58596.4,&quot;total_moving_time&quot;:18719},     
            {&quot;week_number&quot;:1,&quot;total_distance&quot;:41347.5,&quot;total_moving_time&quot;:12796}
          ]
        }
      },
    })
    app.mount(&#39;#demo&#39;)

&lt;!-- language: lang-html --&gt;

    &lt;script src=&quot;https://unpkg.com/vue@3/dist/vue.global.prod.js&quot;&gt;&lt;/script&gt;
    &lt;div id=&quot;demo&quot;&gt;
      &lt;div v-for=&quot;(week, week_index) in activity_weeks&quot; v-bind:value=&quot;week._id&quot;&gt;
        &lt;div class=&quot;container max-w-xl mx-auto&quot;&gt;
          &lt;h2 class=&quot;text-2xl&quot;&gt;Week {{ week }}:&lt;/h2&gt;
          &lt;p&gt;{{ weekly_total_data[week_index]?.total_distance }}&lt;/p&gt;
          &lt;p&gt;{{ weekly_total_data[week_index]?.total_moving_time }}&lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;

&lt;!-- end snippet --&gt;



</details>



# 答案3
**得分**: 0

如果您尝试通过getter访问数据,请确保您的getter是一个计算属性:

```javascript
export default {
  ...,
  computed: {
    matchWeeklyTotals() {
      return this.weekly_total_data;
    }
  }
}

当您在模板中访问它们时,不需要使用括号调用函数,因此您可以直接访问它们:

<h2>
  {{ matchWeeklyTotals[week_index] }}
</h2>

我还建议添加一个检查,以确保该weekIndex的项存在,如果可能的话,匹配week_number的值并使用find函数,或将数组映射成一种形式,以便在某些时候出现数据排序问题时可以直接访问数据。除非有特定原因需要使用多个数组,否则您也可以直接映射weekly_total_data数组。

英文:

If you are trying to access data through a getter, make sure your getter is a computed property

export default {
...,
computed: {
matchWeeklyTotals() {
return this.weekly_total_data;
}
}
}

And when you access them in the template, you don't need to call the function using parenthesis, so you can access them directly as

&lt;h2&gt;
{{ (matchWeeklyTotals[week_index])}}
&lt;/h2&gt;

Also I would recommend adding a check to ensure if the item of that weekIndex exists, and if possible match the week_number number value and use a find function, or map the array in a form where you can access the data directly in case there's a sorting issue in the data at some point. You could also map the weekly_total_data array directly, unless there's a specific reason to have multiple arrays

huangapple
  • 本文由 发表于 2023年5月22日 02:36:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301389.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定