需求

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图数量和内容。
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐