vue 使用动态ref动态显示echarts图坑总结

需求

vue项目中动态给div赋予ref属性,以达到动态显示echarts图数量的目的。

首先说下最开始的实现思路:

  1. 在页面挂载的时候调用接口获取需要图形化展示的参数列表,以及展示图形的数量
  2. 在接口数据接收完毕后调用画echarts图的方法

步骤并不复杂,但是其中涉及到了vue生命周期的坑,分析如下:

  1. 我们是动态给div赋予ref的:

    <template slot="body">
      <el-row class="echarts_box" :gutter="76">
        <el-col v-for="item in count" :span="6" class="rel">
          <div :ref="'chart'+item" class="echarts_item"></div>
        </el-col>
      </el-row>
     </template>
    

    也就是说我们在上边的第一步接收完接口的数据后,会根据接收到的count数量更新DOM内容。

    接下来如果立即执行画echarts图的方法,打印refs内容如下图所示,发现refs内容为空。

    此时我们需要使用this.$nextTick方法,在该方法中回调画echarts图的方法,该方法的作用就相当于延迟调用方法,在DOM更新的时候不会立即执行回调函数,在DOM更新完毕后会执行回调函数。这样我们就可以在画echarts图的方法中获取ref内容。
    在这里插入图片描述

  2. 当DOM更新完毕后在获取ref内容的时候不能使用this.$refs[refName]的方式获取,如下图此方式获取的是对应的ref后的数组,我们需要获取的是数组内的内容,所以要使用this.$refs[refName][0]的方式获取。
    在这里插入图片描述

完整代码实现

<template>
  <CardBox title="智能测试库平台-四川移动" height="100%">
    <template slot="body">
      <el-row class="echarts_box" :gutter="76">
        <el-col v-for="item in count" :span="6" class="rel">
          <div :ref="'chart'+item" class="echarts_item"></div>
        </el-col>
      </el-row>
    </template>
  </CardBox>
</template>

<script>
  import CardBox from '@/components/common/CardBox'
  import api from "../../../service/api";
  import {getCookie} from "../../../service/cookie";

  export default {
    components: {
      CardBox
    },
    mounted() {
      this.product_name = JSON.parse(this.$route.query.info).product_name;
      this.area = JSON.parse(this.$route.query.info).area;
      this.get_param_map()
    },
    data () {
      return {
        count: 0,
        loading: false,
        product_name: '',
        area: '',
        param_list: []
      }
    },
    methods: {
      // 画柱状图
      drawLine (id, title, xdata, data) {
        // 基于准备好的dom,初始化echarts实例
        let myChart = this.$echarts.init(id)
        // 绘制图表
        myChart.setOption({
          title: {
            text: title,
            textStyle: {
              color: '#333',
              fontSize: 14
            }
          },
          grid: {
            x: 0,
            x2: 0,
            y: '20%',
            y2: 0,
            containLabel: true
          },
          tooltip: {},
          xAxis: {
            data: xdata,
            axisLine: {
              show: false
            },
            axisTick: {
              show: false
            },
            axisLabel: {
              color: '#333',
              textStyle: {
                fontSize: 12
              }
            }
          },
          yAxis: {
            axisLabel: {
              color: '#333',
              textStyle: {
                fontSize: 12
              }
            },
            splitLine: {
              lineStyle: {
                type: 'dashed',
                color: '#ccc'
              }
            },
            axisLine: {
              show: false
            },
            axisTick: {
              show: false
            }
          },
          series: [
            {
              name: title,
              type: 'bar',
              barWidth: 16,
              label: {
                show: true,
                position: 'outside',
                formatter: '{c}',
                fontSize: 12,
                textStyle: {
                  color: '#333'
                }
              },
              itemStyle: {
                normal: {
                  barBorderRadius: 30,
                  color: params => {
                    // console.log('params', params)
                    if (params.data > 80 && params.seriesName.indexOf('状态') > -1){
                      return '#db0505'
                    }else {
                      return '#05c9db'
                    }
                  }
                }
              },
              data: data
            }
          ]
        })
      },
      // 获取需要展示的参数
      get_param_map() {
        let data = {
          area: this.area,
          product_name: this.product_name,
          user_id:getCookie('user_id')
        }
        api.operate_data_api.testLib_busniss_platform(data).then(response =>{
          if (response.status === 0) {
            console.log(response.info)
            this.count = response.info.length
            this.param_list = response.info
            this.handle_draw_bar()
          }else {
            this.$message.error('系统异常,请联系管理员!')
          }
        })
      },
      // 将获取的参数画柱状图
      handle_draw_bar() {
        this.$nextTick(() => {
        console.log('this.$refs', this.$refs)
          this.param_list.forEach((item, index) => {
            let chart = 'chart' + (index + 1)
            let title = item.title + '(' + item.unit + ')'
            let data = item.data
            this.drawLine(
              this.$refs[chart][0],
              title,
              ['上月', '当月', '当月目标'],
              data
            )
          })
        })
      }
    }
  }
</script>
<style lang="scss" scoped>
  .echarts_item{
    width: 100%;

  }
  .tips_icon{
    right: 38px;
  }
</style>

效果图展示

动态显示echarts图数量和内容。
在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
首先,您需要在Vue组件中引入ECharts库。然后,您可以在组件的数据中定义ECharts图表的初始配置和数据。接着,您可以使用Vue的数据绑定功能来动态修改您的数据。最后,通过调用ECharts的API方法来重新绘制图表并显示更新后的数据。以下是一个简单的示例代码: 在模板中定义ECharts图表容器 ```vue <template> <div> <div ref="chart" style="height: 400px;"></div> </div> </template> ``` 在组件中引入ECharts并初始化图表 ```vue <script> import echarts from 'echarts'; export default { data() { return { // 初始数据 chartData: [10, 20, 30, 40, 50], // echarts配置 chartOptions: { xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E'] }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: this.chartData }] } }; }, mounted() { // 初始化echarts图表 this.chart = echarts.init(this.$refs.chart); this.chart.setOption(this.chartOptions); } } </script> ``` 在数据更新时重新绘制图表 ```vue <script> import echarts from 'echarts'; export default { data() { return { // 初始数据 chartData: [10, 20, 30, 40, 50], // echarts配置 chartOptions: { xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E'] }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: this.chartData }] } }; }, mounted() { // 初始化echarts图表 this.chart = echarts.init(this.$refs.chart); this.chart.setOption(this.chartOptions); }, methods: { // 修改数据并重新绘制图表 updateChartData() { this.chartData = [20, 30, 40, 50, 60]; this.chart.setOption({ series: [{ data: this.chartData }] }); } } } </script> ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一切如来心秘密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值