Vue 引入Echarts 封装(无内存泄漏问题)

封装ECharts图表
本文介绍如何使用Vue和ECharts封装可复用的图表组件,包括图表初始化、数据更新及内存管理,确保图表在动态更新和路由切换时无内存泄漏。

封装 常用 echarts 图表:

首先需要下载echarts:

// 命令行
npm install echarts --save

接着创建相关js文件,
在这里插入图片描述

代码如下:

import Vue from "vue";
import echarts from "echarts";
let Echarts = function(Vue) {
  Object.defineProperties(Vue.prototype, {
    $chart: {
      get() {
        return {
          // 清除实例
          dispose(...args) {
            args.forEach(item => echarts.dispose(item));
          },
          //示例
          bar(id) {
            this.chart = echarts.init(document.getElementById(id));
            this.chart.clear();
            // 这里定义的optionData 也可作为参数传入,
            const optionData = {
              title: {
                text: "ECharts示例"
              },
              tooltip: {},
              xAxis: {
                data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
              },
              yAxis: {},
              series: [
                {
                  name: "销量",
                  type: "bar",
                  data: [5, 20, 36, 10, 10, 20]
                }
              ]
            };
            this.chart.setOption(optionData, true);
          }
        };
      }
    }
  });
};
Vue.use(Echarts);

这里我封装了一个清除方法,防止内存泄漏。

创建后需要在入口js中引入:
在这里插入图片描述
然后在组件中调用:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div class="about-body" id="first" ref="first"></div>
    <div class="about-body" id="second" ref="second"></div>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  mounted() {
    this.$chart.bar("first"); //方法调用
    this.$chart.bar("second"); //方法调用
    setInterval(() => {
      this.$chart.dispose(this.$refs.first);
      this.$chart.bar("first"); //方法调用
    }, 1000);
  },
  beforeDestroy() {
 // beforeDestroy中无法通过getElementById获取dom元素,所以采用ref方法
    this.$chart.dispose(this.$refs.first, this.$refs.second);
  }
};
</script>
<style lang="scss" scoped>
.about {
  /*<!--$blue: #a3bcff;-->*/
  & {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    width: 100%;
    height: 80vh;
  }
  .about-body {
    width: 100%;
    height: 60vh;
  }
}
</style>

这里我创建了两张图,添加了一个定时器用于测试,经过测试后发现,更新图表数据(先删除再重新建),包括路由切换,都可以完美清除,不会有内存泄漏问题。

更多图表可自行封装。

<think>好的,我现在需要帮助用户解决在Vue2中使用ECharts封装半环形进度组件的问题。用户之前已经得到过一个示例,现在他们再次提问,可能希望得到更详细的解释或进一步的优化。我需要结合用户提供的引用内容,以及之前的回答,来生成一个更完善的解决方案。 首先,回顾用户的历史问题,他们之前得到了一个半圆环进度组件的代码示例,现在用户再次询问可能希望有更多的细节或者不同的实现方式。用户提供的引用中提到了Vue2和Vue3中实现3D轮播图、ECharts封装方法,以及饼图组件的例子。这些引用可能帮助我找到相关的实现技巧,比如如何初始化ECharts实例,如何处理响应式数据,或者如何添加交互事件。 接下来,我需要确保新回答符合用户的要求,即提供一个Vue2中封装半环形进度组件的示例。之前的回答已经包含了一个基本的组件代码,但可能需要进一步优化或解释。同时,用户提到的引用内容中有关于ECharts的初始化和事件处理的部分,如引用[2]和[4]中提到的初始化实例和点击事件,这些可能需要整合到新组件中,以增强功能。 我需要考虑用户可能的深层需求。例如,用户可能希望组件能够响应窗口变化,或者添加动态效果,如进度条动画。此外,用户可能关心如何自定义颜色、调整环形的半径和位置,或者添加中间的百分比显示。这些都是在封装ECharts组件时常见的需求,应该包含在回答中。 然后,我需要检查之前的回答是否有遗漏或可以改进的地方。例如,之前的组件可能没有处理窗口大小变化时的重绘问题,或者没有提供足够的自定义选项。引用[3]提到VueECharts的图表组件封装,可能涉及到如何更好地组织代码结构,提高组件的复用性。因此,在更新回答时,可以加入resize事件监听,或者提供更多的配置选项,如颜色、半径等。 另外,用户提供的引用[1]和[3]提到3D轮播图和饼图组件,这可能暗示用户对视觉效果有较高要求。因此,在示例代码中,可能需要调整ECharts的配置项,使半圆环看起来更美观,比如添加阴影、调整颜色渐变等。同时,引用[4]中的点击事件处理也可以被整合到组件中,允许用户通过事件与组件交互。 在代码实现方面,需要确保ECharts正确引入Vue2项目中,并检查生命周期钩子是否正确使用,比如在mounted中初始化图表,在beforeDestroy中销毁实例以避免内存泄漏。此外,props的定义需要严谨,比如progress的范围验证,颜色参数的默认值设置等。 最后,生成相关问题时要考虑用户可能遇到的后续问题,比如如何优化性能、添加动画效果,或者如何处理多个实例的情况。结合引用中的内容,可以推荐用户参考3D轮播图的实现思路,或者如何封装更复杂的图表组件。</think>根据站内引用内容和最佳实践,以下是一个基于 Vue2 和 ECharts 的**半环形进度组件**完整实现方案,包含动态更新和响应式特性: --- ### 完整组件封装代码 ```vue <template> <div :id="chartId" class="semi-progress-ring" :style="{ width: width, height: height }" ></div> </template> <script> export default { props: { chartId: { type: String, required: true }, // 唯一图表ID value: { type: Number, default: 0 }, // 进度值(0-100) width: { type: String, default: '200px' }, // 容器宽度 height: { type: String, default: '200px' }, // 容器高度 color: { type: String, default: '#36a3f7' }, // 主色 bgColor: { type: String, default: '#eee' }, // 背景色 radius: { type: Array, default: () => ['75%', '90%'] } // 环半径[内,外] }, data() { return { chart: null }; }, watch: { value: { handler(newVal) { this.updateChart(Math.min(Math.max(newVal, 0), 100)); }, immediate: true } }, mounted() { this.initEcharts(); window.addEventListener('resize', this.handleResize); }, beforeDestroy() { window.removeEventListener('resize', this.handleResize); this.chart?.dispose(); }, methods: { initEcharts() { this.chart = this.$echarts.init(document.getElementById(this.chartId)); const option = { series: [{ type: 'pie', hoverAnimation: false, radius: this.radius, center: ['50%', '80%'], // 向下偏移形成半圆 startAngle: 180, // 起始角度 endAngle: 0, // 结束角度 label: { show: false }, data: [ { value: this.value, itemStyle: { color: this.color } }, { value: 100 - this.value, itemStyle: { color: this.bgColor } } ] }] }; this.chart.setOption(option); }, updateChart(newValue) { this.chart?.setOption({ series: [{ data: [ { value: newValue }, { value: 100 - newValue } ] }] }); }, handleResize() { // 窗口缩放时自适应 this.chart?.resize(); } } }; </script> <style scoped> .semi-progress-ring { position: relative; margin: 0 auto; } </style> ``` --- ### 核心特性说明 1. **动态数据绑定** - 通过 `value` 属性接收外部传入的进度值(0-100),配合 `watch` 实现自动更新 - 使用 `Math.min(Math.max(newVal, 0), 100)` 确保数值范围有效性[^3] 2. **视觉配置参数** - 支持自定义颜色 (`color`/`bgColor`)、尺寸 (`width`/`height`)、环宽 (`radius`) - 通过 `center: ['50%', '80%']` 实现半圆效果,调整第二个百分比可控制垂直位置 3. **响应式处理** - 监听 `resize` 事件自动调整图表尺寸 - 组件销毁时自动释放 ECharts 实例资源[^4] --- ### 使用示例(父组件) ```vue <template> <div> <semi-progress-ring chart-id="progress1" :value="progressValue" color="#f56c6c" bg-color="#f0f0f0" :radius="['70%', '95%']" /> <button @click="progressValue += 10">+10%</button> </div> </template> <script> import SemiProgressRing from './components/SemiProgressRing.vue'; export default { components: { SemiProgressRing }, data() { return { progressValue: 30 }; } }; </script> ``` --- ### 增强功能建议(基于引用优化) 1. **添加中心文本** 在环中间显示当前进度值: ```javascript // option 中添加 graphic: [{ type: 'text', left: 'center', top: '60%', style: { text: `${this.value}%`, textAlign: 'center', fill: this.color, fontSize: 24 } }] ``` 2. **交互动画** 参考引用[1]的3D效果,添加渐变过渡: ```javascript animationEasing: 'cubicOut', animationDuration: 1000 ``` 3. **事件绑定** 如引用[4]所述,添加点击事件: ```javascript this.chart.on('click', params => { this.$emit('ring-click', params.dataIndex); }); ``` --- ### 注意事项 1. 需确保已正确安装 `echarts` 并挂载到 Vue 原型: ```javascript // main.js import echarts from 'echarts' Vue.prototype.$echarts = echarts ``` 2. 当需要同时显示多个组件时,必须确保每个实例的 `chartId` 唯一[^2] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_1075654056

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

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

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

打赏作者

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

抵扣说明:

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

余额充值