坦途的博客

vuePress-theme-reco 坦途    2020 - 2025
坦途的博客 坦途的博客
主页
博客
  • 开发实践
  • 技术笔记
  • 技术实践
  • 前端优化
  • 鉴权
  • 心情物语
  • 杂谈游记
  • 前端
标签
时间轴
关于
author-avatar

坦途

22

文章

33

标签

主页
博客
  • 开发实践
  • 技术笔记
  • 技术实践
  • 前端优化
  • 鉴权
  • 心情物语
  • 杂谈游记
  • 前端
标签
时间轴
关于

echarts在vue3+vite使用一点经验

vuePress-theme-reco 坦途    2020 - 2025

echarts在vue3+vite使用一点经验

坦途 2022-08-02 vueechartsvite

介绍

echarts在vue3+vite项目中使用的一点经验

# 一、安装echarts

npm install echarts --save

在页面使用时,需要使用以下两条命令任选其一来使用

import *as echarts from 'echarts' //引入echarts
// 或者
import { echarts } from 'echarts'
//需要使用 ES module 语法,不能使用 CommonJS 的 require。

为什么不能使用let echarts = require('echarts');

  1. Vite 默认使用 ES module 的语法,不能使用 CommonJS 的 require 语法。
  2. echarts 默认导出是一个对象,不能直接赋值给一个变量。

# 二、markRaw 避免不必要重新渲染

我们封装echarts组件时往往会用传值给组件内部,来生成图,但是会发现图里的tooltip悬浮框导致不能使用

这是因为在vue3中使用了proxy对象代理,但echarts实例在vue3中不能是一个响应式对象,否则提示框会显示不出来,需要在代码内部添加vue3的markRaw,他的作用是让一个对象脱离vue的代理和追踪,标记为原始对象,不在转换为proxy。

import { markRaw } from 'vue'

const echartsInstance = echarts.init(dom) 
markRaw(echartsInstance)

# 三、多个图表在同一页面下,设置容器宽高,否则显示空白

动态获取数据时虽然处理数据的代码在前,但图表仍会先加载,所以刚开始加载图表时,如若数据量较大,会先显示空图表。动态id是为了每一个图能够获取到对应的DOM,切换页面时图表id已存在导致的空白页问题。

// 图表初始化
  chart.value = markRaw(
    echarts.init(document.getElementById(assetTrendsList.value.id))
  );
  document.getElementById(assetTrendsList.value.id).setAttribute('_echarts_instance_', '');
  chart.value.setOption(options);

# 四、重新渲染 ECharts 采用重新初始化或更新 options

有几种方案供参考

# 重新初始化echarts实例

// 基于准备好的dom,初始化echarts实例
echarts.init(document.getElementById("monthCollect")).dispose();
var myChart = echarts.init(document.getElementById("monthCollect"));
myChart.setOption()

# 更新options里的值

// 更新 options 触发重新渲染
chart.setOption(newOptions) 

# 五、切换 ECharts 实例避免画布消失

echarts渲染逻辑是: 如果未实例化则进行实例化,在此期间会在Dom容器生成一个_echarts_instance_属性,该属性就是当前echarts的id,再进行后边的渲染操作,当我们刷新已经实例化的echarts图表时,echarts会先匹配该Dom容器上的_echarts_instance_属性值是否与实例对象一样,如果一样则会在原生的结构上进行渲染,但是因为已经破坏原生的结构,所以无法重新渲染出echarts

设置setAttribute('echarts_instance', '');

document.getElementById(assetTrendsList.value.id).setAttribute('_echarts_instance_', '');