Vue+ECharts实现多图表窗口自适应

前言

最近在学前端,也遇到了不少问题,在查阅了不少资料并且自己实验过后得以解决(but不知道为什么,maybe一半玄学),所以在解决这些问题之后想顺便总结一下,以便后来人避坑。

过程中我遇到的问题包括但不限于以下,不过有些是vue-router的问题,这里就不管了,只看echarts

Can't get DOM width or height.

Uncaught TypeError: Cannot read properties of undefined (reading "type").

Initialize failed: invalid dom.

mounted is not defined.

Failed to parse source for import analysis because the content contains invalid JS syntax.

Failed to resolve import "../xxx" from "xxx"

...

一、写一个echarts图表barCharts.vue

我使用的node版本是16.17.1,echarts版本是5.4.0,vue版本是3.2.37,整个项目是使用vue官方推荐的vite搭建的。

1、template、style

这俩部分内容很少而且有关联,就放一起讲了。这里有两种方法,一种是在<div>标签内直接写style="height: xxx ; width: xxx" ,一种是在最后的<style>标签内写,如下。

<style scoped>
#barCharts {
  width: 100%;
  height: 100%;
}
</style>

不过实际测试下来两种写法都没有任何区别,但是也有人说只有<div>标签中的写法才能成功显示图表,如果后一种在<style>标签内写不行的话可以试试。最终这俩部分内容如下:

<template>
  <div  id="barCharts"></div>
</template>

<style scoped>
#barCharts {
  width: 100%;
  height: 100%;
}
</style>

2、script

最开始我使用的写法是最传统的 export default 模式,在这种写法情况下,定义DOM时需要将长宽定义为确定的值,**不能使用百分比,理所当然自适应也就失效了。**不过也还是贴下代码吧:

<script>
import *  as echarts from "echarts";

export default {
  name: "barCharts",

  data(){
    return{
      myChart: null
    }
  },

  mounted() {
    this.initbarCharts();
  },

  methods:{
    initbarCharts(){
      this.myChart = echarts.init(document.getElementById("barCharts"));
    this.myChart.setOption(
        {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: ['项目一' , '项目二', '项目三', '项目四', '项目五']
        },
        series: [
          {
            type: 'bar',
            data: [120,200,300,200,500]
          }
        ]
    }
      );

      window.onresize = () => {
        this.myChart.resize();
      };
  },
}};
</script>

后面我看到有人使用setup()函数+component组件可以实现长宽百分比定义和窗口自适应,所以便舍弃了以上这种写法,这种写法在根实例home.vue中使用会导致报错There is a chart instance already initialized on the dom.

二、写一个根实例home.vue

1、template

在根实例中需要在自定义元素<barCharts> 外再套入一个<div>容器,我在这就命名为home好了

<template>
  <div id="home">
      <barCharts></barCharts>
  </div>
</template>

2、script

根实例中内容较少,只需要将组件导入并注册就可以

<script>
import barCharts from "./components/barCharts.vue";
export default {
  components:{
    barCharts
  }
}
</script>

3、style

在这里需要写上一些内容,具体原理不清,删掉一些就会出错不显示或者图表溢出页面。

<style scoped>
#home {
  width: 100%;
  display: flex;
  flex-flow: column;
  overflow-y: auto;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
</style>

三、使用setup更改组件

具体可查阅官方文档,setup是vue3引入的新特性,语法方面可以查看这篇文章

只需要在原图表文件barCharts.vue的基础上更改<script>内容即可。这里有两种写法,一种是在export default 中写一个setup函数,在其中初始化图表等,如下:

<script>
import {onUnmounted, onMounted} from 'vue'
import * as echarts from "echarts";

export default {
  name: "barCharts",
  setup() {
    let echart = echarts;

    onMounted(() => {
      initBarChart();
    });

    onUnmounted(() => {
      echart.dispose;
    }); 

    function  initBarChart(){
      var  chart1 =echart.init(document.getElementById("barCharts"));

      chart1.setOption(
          {
        xAxis:{
          type:'value'
        },
        yAxis:{
          type:'category',
          data:['项目一' , '项目二', '项目三', '项目四', '项目五']
        },
        series:[
          {
            data:[120,200,300,200,500],
            type:'bar'
          }
        ]
          }
      );
			window.onresize = () => {
        chart1.resize();
      };
    }
  }
};
</script>

另一种写法是在<script> 标签内加入setup,写成<script setup> ,如下:

<script setup>
import {onUnmounted,onMounted} from "vue";
import * as echarts from "echarts";

let echart=echarts;

onMounted(()=>{
  initBarCharts();
});

onUnmounted(()=>{
  echart.dispose();
});

function initBarCharts() {
  var chart1 = echart.init(document.getElementById("barCharts"));
  chart1.setOption(
      {
        xAxis:{
          type:'value'
        },
        yAxis:{
          type:'category',
          data:['项目一' , '项目二', '项目三', '项目四', '项目五']
        },
        series:[
          {
            data:[120,200,300,200,500],
            type:'bar'
          }
        ]
      }
  )
  window.onresize = () => {
    chart1.resize();
  };
}

</script>

两种方法都没有区别,都可以成功显示图表,可以自己挑选。

四、多图表自适应显示

这个其实就是在根实例home.vue中再加入新的图表组件就行,就比如:

<template>
      <p>home</p>
			<barCharts></barCharts>
      <barCharts2></barCharts2>
  </div>
</template>

同时在<script>中导入组件并注册。

另外在这里可能会遇到另一个问题,就是图表可以正常显示出来,但是只有一个图表可以自适应窗口大小,而另一个不变。(我第一次出现了,但之后又没出现,十分玄学)如果有遇到这个问题的话只需要将图表组件中的窗口监听函数替换就可以。

	//原使用监听函数
  // window.onresize = () => {
  //   chart1.resize();
  // };
  //将其更改为
  window.addEventListener('resize', function () {
    chart1.resize()
  })

总结

刚开始接触VUE和Echarts,可能有很多表达不准确的地方,请各位大佬多多包涵,有问题可以指出,大家共同进步。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值