vue项目中使用ECharts,避免浏览器卡死的解决方案
作者:一身温柔气
Vue中ECharts图表过多易导致页面卡死,建议全局引入并动态销毁实例,避免资源堆积,代码示例包含样式配置,可根据需求调整
在vue项目中常遇到echarts图表使用过多页面卡死的情况,以下只展示了一个折线图,可通过同样方式增加多个,通过以下方法每执行一次清除一次即可。
1、从npm获取
npm install echarts --save
2、在 main.js引入echarts
import * as echarts from 'echarts'; Vue.prototype.$echarts = echarts;
3、完整代码
(图表中加了其他样式,可根据自己喜欢更改)
<template> <div> <div class="container"> <div id="linePicture"></div> </div> </div> </template> <script> //全局定义chart,离开页面时直接清除chart; let chart = null; export default { data() { return {}; }, // 页面初始化挂载dom mounted() { window.addEventListener("beforeunload", this.clearChart); this.linePictures("linePicture"); }, methods: { clearChart() { // 手动触发 destroy 相关的生命周期 this.$destroy(); }, linePictures(id) { //心率/呼吸率 // 时间轴 var xdata = [ "00:38", "00:39", "00:40", "00:41", "00:42", "00:43", "00:44", "00:45", "00:46", "00:47", "00:48", "00:49", "00:50", "00:51", "00:52", "00:53", "00:54", "00:55", "00:56", "00:57", "00:58", "00:59", "01:00", ]; //线条一数据 var adata = [ 0, 17, 17, 17, 18, 20, 22, 23, 0, 18, 19, 19, 19, 19, 19, 18, 18, 18, 0, 0, 21, 19, 0, ]; //线条二数据 var bdata = [ 0, 0, 54, 54, 54, 54, 54, 54, 53, 53, 53, 54, 54, 54, 54, 54, 53, 53, 0, 0, 59, 59, 57, ]; //判断为0不展示,页面展示为0的线不渲染,如想将0也展示可删除; for (var i = 0; i < adata.length; i++) { if (adata[i] == 0) { adata[i] = "-"; } } //第二条线判断同上; for (var i = 0; i < bdata.length; i++) { if (bdata[i] == 0) { bdata[i] = "-"; } } //判断chart,清除上次数据,防止消耗内存; if (chart !== null) { chart.dispose(); chart = null; } if (!chart) { chart = this.$echarts.init(document.getElementById(id), "classic", { renderer: "svg", }); chart.setOption({ title: { top: -5, left: 0, text: "{a|}" + " " + "心率与呼吸率动态",//展示的标题 textStyle: { fontSize: 17, color: "#000", fontWeight: 500, rich: { a: { color: "#FFF", //设置 动态数据字体的颜色 fontSize: "12", //设置 动态数据字体的大小 height: 23, width: 23, backgroundColor: { image: require(`../../../assets/heart.png`),//头部标题图片 }, }, }, }, }, tooltip: { trigger: "axis", }, legend: { top: 4, //图例距离左的距离 right: 7, y: "center", //图例上下居中 orient: "vertical", itemGap: 32, height: "20", selectedMode: false, // 图例选择的模式, data: ["呼吸率", "心率"], textStyle: { fontSize: 13, color: "#989ca7", }, // data:types }, grid: { top: "29%", right: "2%", left: "1%", bottom: "5%", containLabel: true, }, xAxis: { //横坐标 name: "", scale: true, type: "category", boundaryGap: true, data: xdata, nameGap: 25, //坐标轴名称与轴线之间的距离 (用数字表示) nameRotate: 0, //坐标轴名字旋转的角度值 inverse: false, //是否为反向坐标轴 axisLine: { //坐标轴轴线设置 show: true, //是否显示坐标轴轴线 }, axisLabel: { //坐标轴刻度文字的设置 show: true, //是否显示 fontSize: 11, //坐标轴刻度文字的大小 (用数字表示) }, }, yAxis: { name: "", type: "value", show: true, //是否显示 y 轴 position: "bottom", //y轴的位置 (可选位置top bottom) offset: 0, //y轴相对于默认位置的偏移,在相同的 position 上有多个 X 轴的时候有用 nameGap: 25, //坐标轴名称与轴线之间的距离 (用数字表示) axisLine: { //坐标轴轴线设置 show: true, //是否显示坐标轴轴线 lineStyle: { //坐标轴的线 width: 1.2, //线的粗细程度 (用数字表示) type: "solid", //线的类型 (可选solid dotted dashed) opacity: 1, //线的透明度 (用0~1的小数表示) }, }, axisTick: { //坐标轴刻度设置 show: true, //是否显示坐标轴刻度 alignWithLabel: true, //刻度线是否和标签对齐 length: 5, //坐标轴刻度长度 lineStyle: { //坐标轴刻度的样式 width: 1.2, //坐标轴刻度的粗细程度 (用数字表示) type: "solid", //坐标轴刻度的类型 (可选solid dotted dashed) }, }, axisLabel: { //坐标轴刻度文字的设置 show: true, //是否显示 inside: false, //坐标轴刻度文字指向 (true表示向上 false表示向下) margin: 10, //坐标轴刻度文字与轴线之间的距离 fontSize: 10, //坐标轴刻度文字的大小 (用数字表示) padding: [8, 0, 2, -5], //坐标轴刻度文字的边距 (上右下左) }, splitLine: { //网格线 show: true, //是否显示 lineStyle: { //网格线样式 color: "#b7b5b5", //网格线颜色 width: 1.3, //网格线的加粗程度 type: "dashed", //网格线类型 }, }, }, series: [ { name: "呼吸率", type: "line", smooth: true, symbol: "none", data: adata, }, { name: "心率", type: "line", smooth: true, symbol: "none", data: bdata, }, ], }); } }, }, //离开页面时需清除图表,避免占用内存,导致页面卡死; beforeDestroy() { if (!chart) { return; } chart.dispose(); chart = null; // 清空 beforeunload 事件处理函数 window.removeEventListener("beforeunload", this.clearChart); }, }; </script> <style scoped> .container { width: 50%; height: 400px; padding: 15px 30px; background: #fff; margin-bottom: 20px; } #linePicture { width: 100%; height: 380px; } </style>
效果展示:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。