移动端echarts折线图结合vant的tab标签实战中遇到坑点

实现以下效果


image.png

结构

<div class="charts">
        <van-tabs v-model="active" @click="onClick" line-height='1px' title-active-color='#009E96' color='#009E96'>
          <van-tab title="美元">
              <div ref="dollarChart" class="mychart"></div>
          </van-tab>
          <van-tab title="港币">
              <div ref="hkdChart" class="mychart"></div>
          </van-tab>
          <van-tab title="日元">
              <div ref="yenChart" class="mychart"></div>
          </van-tab>
          <van-tab title="欧元">
              <div ref="eurChart" class="mychart"></div>
          </van-tab>
        </van-tabs>
 </div>

一开始,按照以下思路实现会出现各种问题

<script>
export default {
  data () {
    return {
     
    }
  },
  created () {
     this.updateData();
  },
  methods: {
   // 接口一次性回来全部数据
    updateData() {
      this.$http.post('/pweb/pweb-transfer.MyForeignQry.do', {}).then(res=>{
        if( res._RejCode==='000000' ){
          this.dataMap = res.DataMap
          // 处理echarts数据
          for (let key of Object.keys(this.dataMap)){
              if(key === 'UsdMap'){ // 美元
                  this.dollarCurrencyDate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencyDate
                  })
                  this.dollarCurrencyBuyRate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.dollarCurrencySaleRate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'EurMap'){ // 欧元
                  this.eurCurrencyDate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencyDate
                  })
                  this.eurCurrencyBuyRate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.eurCurrencySaleRate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'JpyMap'){ // 日元
                  this.yenCurrencyDate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencyDate
                  })
                  this.yenCurrencyBuyRate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.yenCurrencySaleRate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'HkdMap'){ // 港币
                  this.hkdCurrencyDate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencyDate
                  })
                  this.hkdCurrencyBuyRate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.hkdCurrencySaleRate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencySaleRate
                  })
              }
          }
          // 美元
          let Data = this.dollarCurrencyDate
          let BuyRate = this.dollarCurrencyBuyRate.map(Number)
          let SaleRate = this.dollarCurrencySaleRate.map(Number)
          // this.setChart(Data,BuyRate,SaleRate)
          this.$nextTick(() => {
                this.setChart(Data,BuyRate,SaleRate)
           })
        }
      })
    },
   setChart(Data,BuyRate,SaleRate) {
      let dollarChart = this.$echarts.init(this.$refs.dollarChart)
      let eurChart = this.$echarts.init(this.$refs.eurChart)
      let yenChart = this.$echarts.init(this.$refs.yenChart)
      let hkdChart = this.$echarts.init(this.$refs.hkdChart)
      let dollarOption = {
        tooltip: {
            trigger: 'axis'
        },
        legend: {
          type: 'plain',
          left: 'left',
          data: ['买入汇率', '卖出汇率']
        },
        xAxis: {
          type: 'category',
          axisLabel : {//坐标轴刻度标签的相关设置。
            interval:0,
            rotate:"45"
          },
          data: Data
        },
        yAxis: {
          type: 'value',
          max : 6.7,
          min : 6.0,
          splitNumber : 7
        },
        series: [
          {
            name: '买入汇率',
            data: BuyRate,
            type: 'line'
          },
          {
            name: '卖出汇率',
            data: SaleRate,
            type: 'line'
          }
        ]
      }
      let eurOption = {
        tooltip: {
            trigger: 'axis'
        },
        legend: {
          type: 'plain',
          left: 'left',
          data: ['买入汇率', '卖出汇率']
        },
        xAxis: {
          type: 'category',
          axisLabel : {//坐标轴刻度标签的相关设置。
            interval:0,
            rotate:"45"
          },
          data: this.eurCurrencyDate
        },
        yAxis: {
          type: 'value',
          max : 7.8,
          min : 7.4,
          splitNumber : 7
        },
        series: [
          {
            name: '买入汇率',
            data: this.eurCurrencyBuyRate.map(Number),
            type: 'line'
          },
          {
            name: '卖出汇率',
            data: this.eurCurrencySaleRate.map(Number),
            type: 'line'
          }
        ]
      }
      let yenOption = {
        tooltip: {
            trigger: 'axis'
        },
        legend: {
          type: 'plain',
          left: 'left',
          data: ['买入汇率', '卖出汇率']
        },
        xAxis: {
          type: 'category',
          axisLabel : {//坐标轴刻度标签的相关设置。
            interval:0,
            rotate:"45"
          },
          data: this.yenCurrencyDate
        },
        yAxis: {
          type: 'value',
          max : 0.4,
          min :  0,
          splitNumber : 7
        },
        series: [
          {
            name: '买入汇率',
            data: this.yenCurrencyBuyRate.map(Number),
            type: 'line'
          },
          {
            name: '卖出汇率',
            data: this.yenCurrencySaleRate.map(Number),
            type: 'line'
          }
        ]
      }
      let hkdOption = {
        tooltip: {
            trigger: 'axis'
        },
        legend: {
          type: 'plain',
          left: 'left',
          data: ['买入汇率', '卖出汇率']
        },
        xAxis: {
          type: 'category',
          axisLabel : {//坐标轴刻度标签的相关设置。
            interval:0,
            rotate:"45"
          },
          data: this.hkdCurrencyDate
        },
        yAxis: {
          type: 'value',
          max : 1.1,
          min : 0.7,
          splitNumber : 7
        },
        series: [
          {
            name: '买入汇率',
            data: this.hkdCurrencyBuyRate.map(Number),
            type: 'line'
          },
          {
            name: '卖出汇率',
            data: this.hkdCurrencySaleRate.map(Number),
            type: 'line'
          }
        ]
      }
      dollarChart.setOption(dollarOption)
      eurChart.setOption(eurOption)
      yenChart.setOption(yenOption)
      hkdChart.setOption(hkdOption)
    },

  },
  
}
</script>

上述代码在web端结合element的tab可以实现效果
但在手机端会出现问题
具体如下
一 由于echarts的dom和数据是异步的,如果没有使用nextTick会出现如下报错


image.png

解决办法是使用nextTick让数据回来后,等待下一次dom更新完毕后再渲染页面
具体是在created阶段使用nextTick
上述,将nextTick放在拿数据的方法里,依然报上述错误

二 于是给了nextTick后,则报如下错误


image.png

报错 Error in nextTick: "TypeError: Cannot read property 'children' of undefined"

解决:加一个判断 if (数据存在),再执行this.nextTick()方法

三 在setChart方法中,需要给echarts定义dom,这里由于一开始只拿到了美元的div,其他div取不到,这样会导致美元的图也显示不出来

     let dollarChart = this.$echarts.init(this.$refs.dollarChart)
   // 下面三个div获取不到,导致后面流程走不了,因此美元也展示不了图
      let eurChart = this.$echarts.init(this.$refs.eurChart)
      let yenChart = this.$echarts.init(this.$refs.yenChart)
      let hkdChart = this.$echarts.init(this.$refs.hkdChart)

一开始,总是觉得nextTick没有用对地方,导致数据回来dom没更新(因为在web端这样做是可行的),但没想到是这里出现了关键的问题,后面通过打印div才发现只拿到了一个div,length为1


image.png

这个关键问题找出后,后面的问题就迎刃而解!

解决思路
通过tab提供的click事件,点击一次,则初始化一次dom元素,之后再拿数据去画图,这个时候还是要用到nextTick,以保证dom更新完毕后再把数据渲染上去(因为数据在created就已经拿到)

直接上代码

// 在created()里使用this.$nextTick()可以等待dom生成以后再来获取dom对象
 created () {  
     this.$nextTick(() => {
                 this.updateData();
     })
  },

 methods: {
   // tab的点击事件
    onClick(name, title){
        if(title === '港币'){
          this.$nextTick(()=>{
              let hkdChart = this.$echarts.init(this.$refs.hkdChart)
              let hkdOption = {
                  tooltip: {
                      trigger: 'axis'
                  },
                  legend: {
                    type: 'plain',
                    left: 'left',
                    top:'12px',
                    data: ['买入汇率', '卖出汇率']
                  },
                  xAxis: {
                    type: 'category',
                    axisLabel : {//坐标轴刻度标签的相关设置。
                      interval:0,
                      rotate:"45"
                    },
                    data: this.hkdCurrencyDate
                  },
                  yAxis: {
                    type: 'value',
                    max : 1.1,
                    min : 0.7,
                    splitNumber : 7
                  },
                  series: [
                    {
                      name: '买入汇率',
                      data: this.hkdCurrencyBuyRate.map(Number),
                      type: 'line'
                    },
                    {
                      name: '卖出汇率',
                      data: this.hkdCurrencySaleRate.map(Number),
                      type: 'line'
                    }
                  ]
                }
               hkdChart.setOption(hkdOption)
          })
        }else if(title === '日元'){
          this.$nextTick(()=>{
              let yenChart = this.$echarts.init(this.$refs.yenChart)
              let yenOption = {
                  tooltip: {
                      trigger: 'axis'
                  },
                  legend: {
                    type: 'plain',
                    left: 'left',
                    top:'12px',
                    data: ['买入汇率', '卖出汇率']
                  },
                  xAxis: {
                    type: 'category',
                    axisLabel : {//坐标轴刻度标签的相关设置。
                      interval:0,
                      rotate:"45"
                    },
                    data: this.yenCurrencyDate
                  },
                  yAxis: {
                    type: 'value',
                    max : 0.4,
                    min :  0,
                    splitNumber : 7
                  },
                  series: [
                    {
                      name: '买入汇率',
                      data: this.yenCurrencyBuyRate.map(Number),
                      type: 'line'
                    },
                    {
                      name: '卖出汇率',
                      data: this.yenCurrencySaleRate.map(Number),
                      type: 'line'
                    }
                  ]
                }
              yenChart.setOption(yenOption)
          })
        }else if(title === '欧元'){
          this.$nextTick(()=>{
              let eurChart = this.$echarts.init(this.$refs.eurChart)
              let eurOption = {
                  tooltip: {
                      trigger: 'axis'
                  },
                  legend: {
                    type: 'plain',
                    left: 'left',
                    top:'12px',
                    data: ['买入汇率', '卖出汇率']
                  },
                  xAxis: {
                    type: 'category',
                    axisLabel : {//坐标轴刻度标签的相关设置。
                      interval:0,
                      rotate:"45"
                    },
                    data: this.eurCurrencyDate
                  },
                  yAxis: {
                    type: 'value',
                    max : 7.8,
                    min : 7.4,
                    splitNumber : 7
                  },
                  series: [
                    {
                      name: '买入汇率',
                      data: this.eurCurrencyBuyRate.map(Number),
                      type: 'line'
                    },
                    {
                      name: '卖出汇率',
                      data: this.eurCurrencySaleRate.map(Number),
                      type: 'line'
                    }
                  ]
                }
              eurChart.setOption(eurOption)
          })
        }
    },
    updateData() {
      this.$http.post('/pweb/pweb-transfer.MyForeignQry.do', {}).then(res=>{
        if( res._RejCode==='000000' ){
          this.dataMap = res.DataMap
          // 处理echarts数据
          for (let key of Object.keys(this.dataMap)){
              if(key === 'UsdMap'){ // 美元
                  this.dollarCurrencyDate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencyDate
                  })
                  this.dollarCurrencyBuyRate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.dollarCurrencySaleRate = this.dataMap.UsdMap.UsdList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'EurMap'){ // 欧元
                  this.eurCurrencyDate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencyDate
                  })
                  this.eurCurrencyBuyRate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.eurCurrencySaleRate = this.dataMap.EurMap.EurList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'JpyMap'){ // 日元
                  this.yenCurrencyDate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencyDate
                  })
                  this.yenCurrencyBuyRate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.yenCurrencySaleRate = this.dataMap.JpyMap.JpyList.map(item => {
                    return item.CurrencySaleRate
                  })
              }else if(key === 'HkdMap'){ // 港币
                  this.hkdCurrencyDate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencyDate
                  })
                  this.hkdCurrencyBuyRate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencyBuyRate
                  })
                  this.hkdCurrencySaleRate = this.dataMap.HkdMap.HkdList.map(item => {
                    return item.CurrencySaleRate
                  })
              }
          }
          // 美元
          let Data = this.dollarCurrencyDate
          let BuyRate = this.dollarCurrencyBuyRate.map(Number)
          let SaleRate = this.dollarCurrencySaleRate.map(Number)
          let this_ = this
          if(Data && BuyRate && SaleRate){   // 先判断一下是否有数据,否则会报nextTick的错误
            this_.setChart(Data,BuyRate,SaleRate)
          }
        }
      })
    },
   setChart(Data,BuyRate,SaleRate) {
      let dollarChart = this.$echarts.init(this.$refs.dollarChart)
      let dollarOption = {
          tooltip: {
              trigger: 'axis'
          },
          legend: {
            type: 'plain',
            left: 'left',
            top:'12px',
            data: ['买入汇率', '卖出汇率']
          },
          xAxis: {
            type: 'category',
            axisLabel : {//坐标轴刻度标签的相关设置。
              interval:0,
              rotate:"45"
            },
            data: Data
          },
          yAxis: {
            type: 'value',
            max : 6.7,
            min : 6.3,
            splitNumber : 7
          },
          series: [
            {
              name: '买入汇率',
              data: BuyRate,
              type: 'line'
            },
            {
              name: '卖出汇率',
              data: SaleRate,
              type: 'line'
            }
          ]
        }
      dollarChart.setOption(dollarOption)
    },
  },
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容