【问题标题】:Calculate and display percentage difference for every object in an array in Vue Vuetify data table计算并显示 Vue Vuetify 数据表中数组中每个对象的百分比差异
【发布时间】:2021-09-28 01:52:00
【问题描述】:

我正在从如下所示的 JSON 文件接收数据:

{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80},  "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}

我稍后在 Vuetify 表中显示这些数据,我想要实现的是用我的百分比计算逻辑填充 thirtyDaysDiff 列。我的逻辑有效并且该字段被填充,但我必须为数组中的每个对象手动编写它,这是我想避免的。

如何为数组中的每个对象应用以下逻辑,而不是为每个对象手动执行?

逻辑:

 calculateThirtyDayDifference() {
    let calculatedPercent = 100 * Math.abs( ( this.bitcoinInfo[0]['7d'] - this.bitcoinInfo[0]['30d'] ) / ( (this.bitcoinInfo[0]['7d']+this.bitcoinInfo[0]['30d'])/2 ) )
    let roundedCalculatedPercent = Math.max( Math.round(calculatedPercent  * 10) / 10, 2.8 ).toFixed(2)
    this.bitcoinInfo[0].thirtyDaysDiff = roundedCalculatedPercent

    let secondCalculatedPercent = 100 * Math.abs( ( this.bitcoinInfo[1]['7d'] - this.bitcoinInfo[1]['30d'] ) / ( (this.bitcoinInfo[1]['7d']+this.bitcoinInfo[0]['30d'])/2 ) )
    let secondRoundedCalculatedPercent = Math.max( Math.round(secondCalculatedPercent  * 10) / 10, 2.8 ).toFixed(2)
    this.bitcoinInfo[1].thirtyDaysDiff = secondRoundedCalculatedPercent
}

我尝试使用forEach 进行操作,但没有成功。这是我的整个组件:

<template>
<div>
  <v-data-table
    :headers="headers"
    :items="bitcoinInfo"
    :hide-default-footer="true"
    :class="{active: group && item.id == group.id}"
  >

  </v-data-table>
</div>

</template>

<script>
import axios from 'axios';

  export default {
    data () {
      return {
        bitcoinInfo: [],
        headers: [
          {
            text: 'Currency',
            align: 'start',
            value: 'currency',
          },
          
          { text: '30 Days Ago', value: '30d' },
          { text: '30 Day Diff %', value: 'thirtyDaysDiff'},
          { text: '7 Days Ago', value: '7d' },
          { text: '7 Day Diff %', value: 'sevenDaysDifference' },
          { text: '24 Hours Ago', value: '24h' },
        ],
      }
    },

    methods: {
      getBitcoinData() {
        axios
      .get('data.json')
      .then((response => {

      var convertedCollection =  Object.keys(response.data).map(key => {
            return {currency: key, thirtyDaysDiff: 0, sevenDaysDifference: 0,  ...response.data[key]}
          })

          this.bitcoinInfo = convertedCollection
          
      }))
      .catch(err => console.log(err))
        },

        calculateThirtyDayDifference() {
            let calculatedPercent = 100 * Math.abs( ( this.bitcoinInfo[0]['7d']  - this.bitcoinInfo[0]['30d'] ) / ( (this.bitcoinInfo[0]['7d']+this.bitcoinInfo[0]['30d'])/2 ) )
            let roundedCalculatedPercent = Math.max( Math.round(calculatedPercent  * 10) / 10, 2.8 ).toFixed(2)
            this.bitcoinInfo[0].thirtyDaysDiff = roundedCalculatedPercent


            let secondCalculatedPercent = 100 * Math.abs( ( this.bitcoinInfo[1]['7d']  - this.bitcoinInfo[1]['30d'] ) / ( (this.bitcoinInfo[1]['7d']+this.bitcoinInfo[0]['30d'])/2 ) )
            let secondRoundedCalculatedPercent = Math.max( Math.round(secondCalculatedPercent  * 10) / 10, 2.8 ).toFixed(2)
            this.bitcoinInfo[1].thirtyDaysDiff = secondRoundedCalculatedPercent

           
        }
      },
           
      mounted() {
        this.getBitcoinData()
      },
      updated() {
         this.calculateThirtyDayDifference()
      }
  }

</script>

【问题讨论】:

    标签: javascript arrays vue.js vuetify.js


    【解决方案1】:

    我建议使用插槽,并即时计算显示值。

    Vuetify 允许您使用 slot
    item.&lt;column-key-name&gt; 自定义特定列单元格的呈现(我更喜欢使用 #slotName 语法,但您也可以使用 v-slot:slotName):

    <template #item.thirtyDaysDiff="{ item }">
      {{ calculateThirtyDayDifference(item) }}%
    </template>
    

    这允许我们将每一行的数据(通过槽的item 属性)提供给计算函数,然后通过简单地为每一行调用函数来显示每一行的计算值。

    以这种方式使用函数的缺点是在每次渲染时都会被重新调用和重新计算,但用于不会导致任何性能问题的简单计算。


    这是一个使用您的测试数据的功能齐全的示例:

    new Vue({
      // ## Required for snippet only ##
      el: '#app', template: '#app-template', vuetify: new Vuetify(),
      // #########
      data() {
        return {
          bitcoinInfo: [],
          headers: [{text:"Currency",align:"start",value:"currency"},{text:"30 Days Ago",value:"30d"},{text:"30 Day Diff %",value:"thirtyDaysDiff"},{text:"7 Days Ago",value:"7d"},{text:"7 Day Diff %",value:"sevenDaysDifference"},{text:"24 Hours Ago",value:"24h"}],
        }
      },
      methods: {
        calculateThirtyDayDifference(item) {
          let calculatedPercent = 100 * Math.abs((item['7d'] - item['30d']) / ((item['7d'] + item['30d']) / 2));
          return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
        }
      },
      computed: {
        thirtyDayDiffArray() {
          return 1;
        },
      },
      mounted() {
        // Load sample data
        let sampleData = JSON.parse('{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80},  "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}');
        this.bitcoinInfo = Object.keys(sampleData)
          .map(key => ({
            currency: key,
            sevenDaysDifference: 0,
            ...sampleData[key]
          })
        );
      },
    })
    <!-- Import Vuetify and Vue for snippet -->
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"><link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"><link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
    
    <!-- Target container for Vue to render into -->
    <div id="app"></div>
    
    <!-- Template that Vue will use --> 
    <script type="text/x-template" id="app-template">
      <v-app>
        <v-data-table
          :headers="headers"
          :items="bitcoinInfo"
          :hide-default-footer="true"
        >
          <template #item.thirtyDaysDiff="{ item }">
            {{ calculateThirtyDayDifference(item) }}%
          </template>
        </v-data-table>
      </v-app>
    </script>

    【讨论】:

      猜你喜欢
      • 2012-09-08
      • 2023-03-21
      • 1970-01-01
      • 2016-07-12
      • 2020-11-27
      • 2019-03-02
      • 2021-11-24
      • 2022-11-29
      • 1970-01-01
      相关资源
      最近更新 更多