You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js实现列表数值按时段计算并展示平均值求助

Vue.js 实时货币价格平均值计算问题修复

我正在开发一个Vue.js项目,通过Coinbase API每隔1分钟获取货币价格并存入amountList数组,需要实现以下功能:

  • 计算最近5分钟(数组中最后5个值)、30分钟(最后30个值)、60分钟(最后60个值)的价格平均值;
  • 在三个独立区域分别展示对应时段的平均值。

当前代码无法正确实现需求,原代码如下:

原模板代码

<template>
  <div id="app" >
    <form>
      <label>Enter Currency: <input type="text" v-model="currency"></label>
      <input id="clickMe" type="button" value="Submit"  @click="getData(currency) "/>
    </form>
    
    <pre></pre><p>Bitcoin Value is : {{ apiData?.data?.amount }}</p>

    <template v-for="value in getShortList(5)">
      <pre></pre><p>Last 5 minute value is : {{ }} </p>
      <li class="divider" role="presentation"></li>
    </template>

    <template v-for="item in getShortList(29)">
      <pre></pre><p>Last 30 minute value is : {{parseInt (getShortList(29))}}</p>
      <li class="divider" role="presentation"></li>
    </template>

    <template v-for="item in getShortList(59)">
      <pre></pre><p>Last 60 minute value is : {{ parseInt (getShortList(59)) }}</p>
      <li class="divider" role="presentation"></li>
    </template>

    <template>
      <div>
        <apexchart width="500" type="bar" :options="options" :series="amountList"></apexchart>
      </div>
    </template>
  </div>
</template>

原脚本代码

import axios from 'axios'

export default {
  data() {
    return {
      apiEndPoint : 'https://api.coinbase.com/v2/prices/spot?currency=',
      apiData: [],
      amountList: [],
    }
  },
  created () {
    this.getData(this.currency);
  },
  methods: {
    getShortList(shortListSize) {
      return this.amountList.slice(0, shortListSize);
    },
    getData(currency) {
      axios.get(`${this.apiEndPoint}${currency}`).then((response) => {
        this.timer = setInterval(() => {
          this.apiData = response.data
          this.amountList.push(response.data.data.amount)
          console.log(this.amountList)
        }, 5000) 
      })
    }
  }
}

问题分析与修复步骤

  1. 初始化缺失与定时器逻辑错误

    • data中未定义currency,导致created钩子调用getData时参数无效;
    • 原定时器内未重新发起API请求,始终使用第一次请求的结果,且间隔设置为5秒(需求是1分钟);
    • 需在定时器内重复调用API,同时修正间隔为60000毫秒。
  2. 数组切片方向错误

    • getShortList使用slice(0, size)取的是数组最前面的旧数据,而最近的数据应该用slice(-size)取数组末尾的最新值。
  3. 平均值计算逻辑缺失

    • 新增计算平均值的方法,将指定数量的价格转换为数字后求和再取平均。
  4. 模板渲染逻辑错误

    • 无需用v-for循环展示平均值,直接调用计算方法即可;
    • 修正apiData初始值为null,避免类型错误。
  5. 内存泄漏防护

    • 在组件销毁时清除定时器,防止内存泄漏。

修复后的完整代码

模板部分

<template>
  <div id="app">
    <form>
      <label>Enter Currency: <input type="text" v-model="currency"></label>
      <input id="clickMe" type="button" value="Submit" @click="startFetching(currency)" />
    </form>

    <p>Current {{ currency }} Value: {{ apiData?.data?.amount }}</p>

    <div class="average-section">
      <p>Last 5 Minutes Average: {{ calculateAverage(5) }}</p>
      <li class="divider" role="presentation"></li>
    </div>

    <div class="average-section">
      <p>Last 30 Minutes Average: {{ calculateAverage(30) }}</p>
      <li class="divider" role="presentation"></li>
    </div>

    <div class="average-section">
      <p>Last 60 Minutes Average: {{ calculateAverage(60) }}</p>
      <li class="divider" role="presentation"></li>
    </div>

    <div>
      <apexchart width="500" type="bar" :options="options" :series="formatChartData()"></apexchart>
    </div>
  </div>
</template>

脚本部分

import axios from 'axios'

export default {
  data() {
    return {
      apiEndPoint: 'https://api.coinbase.com/v2/prices/spot?currency=',
      apiData: null,
      amountList: [],
      currency: '',
      timer: null
    }
  },
  beforeUnmount() {
    // 清除定时器防止内存泄漏
    if (this.timer) {
      clearInterval(this.timer)
    }
  },
  methods: {
    getRecentPrices(size) {
      // 取数组末尾的最新size个值
      return this.amountList.slice(-size)
    },
    calculateAverage(size) {
      const recentPrices = this.getRecentPrices(size)
      if (recentPrices.length === 0) return 'N/A'
      // 转换为数字并计算平均值,保留两位小数
      const sum = recentPrices.reduce((total, price) => total + parseFloat(price), 0)
      return (sum / recentPrices.length).toFixed(2)
    },
    async fetchPrice(currency) {
      try {
        const response = await axios.get(`${this.apiEndPoint}${currency}`)
        this.apiData = response.data
        this.amountList.push(response.data.data.amount)
        // 限制数组长度,只保留最近60条数据(对应60分钟)
        if (this.amountList.length > 60) {
          this.amountList.shift()
        }
      } catch (error) {
        console.error('Failed to fetch price:', error)
      }
    },
    startFetching(currency) {
      // 先清除之前的定时器
      if (this.timer) {
        clearInterval(this.timer)
      }
      this.currency = currency
      // 立即获取一次数据
      this.fetchPrice(currency)
      // 设置1分钟间隔的定时器
      this.timer = setInterval(() => {
        this.fetchPrice(currency)
      }, 60000)
    },
    formatChartData() {
      // 适配apexchart的series格式
      return [{
        name: `${this.currency} Price`,
        data: this.amountList.map(price => parseFloat(price))
      }]
    }
  }
}

关键改进点

  • 新增fetchPrice方法封装API请求逻辑,确保每次定时器触发都重新获取最新价格;
  • calculateAverage方法负责计算指定时段的平均值,保留两位小数;
  • 限制amountList长度不超过60,避免数组无限增长;
  • 组件销毁时清除定时器,防止内存泄漏;
  • 修正图表数据格式,适配apexchart要求的数组结构。

内容的提问来源于stack exchange,提问作者takis Paras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:35:24