解决echart在vue中id重复问题
作者:一码哥
这篇文章主要介绍了解决echart在vue中id重复问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
echart在vue中id重复问题
封装的echarts组件重复调用时,id重复会导致页面不渲染,数据覆盖等一系列问题
解决方法
用ref解决了问题
解决方法:
//修改前 <div id="echart"></div> //修改后 <div ref="echart"></div>
初始化调用时,document.getElementById(‘xxx’)
改成 this.$refs.xxx
//修改前 var myChart = this.$echarts.init(document.getElementById('echart')); //修改后 var myChart = this.$echarts.init(this.$refs.echart);
组件调用
//1 <echart :data="myData"></echart > //2再次调用 <echart :data="myData"></echart >
Echarts图表复用解决id唯一性
目前市面上许多项目都会接触到可视化大屏的开发,用得最多的三方组件库Echarts,在进行封装后复用许多同学会发现页面渲染异常问题,只会渲染第一次复用的内容.究其原因在于我们通过Id获取了页面节点进行渲染造成了id的重复.
网上也有许多的解决方案.在此,给大家分享一个自己测试后的可行的实施方案.我们可以通过uuid生成不同的id向子组件传值指定唯一性,也可以通过随机数的方式.
具体的操作我们接着往下看.
首先我们需要将需要复用的组件进行简单的封装. commonEcharts.vue(子组件)
<template> <div :id="id"></div> </template> <script setup> import { number } from 'echarts'; import { ref, inject, onMounted, onUnmounted, defineProps } from 'vue' import useDraw from '/src/util/useDraw.js' const { appRef, calcRate, windowDraw, unWindowDraw } = useDraw() const echarts = inject('$echarts') let { id, option } = defineProps({ option: Object, id: String }) let tuChart = () => { let eg = document.getElementById(id) eg.removeAttribute('_echarts_instance_') const myChart = echarts.init(eg) myChart.setOption(option) window.addEventListener("resize", function () { myChart.resize() }) } onMounted(() => { windowDraw() calcRate() tuChart() }) onUnmounted(() => { unWindowDraw() }) </script> <style lang="scss" scoped> #tu { width: 615px; height: 300px; border: 1px solid gray; margin-top: 15px; } </style>
然后在需要使用的组件中父组件()引入对应的组件.expControl.vue
import charts from '../../../components/copycompnents/commonEcharts.vue'
接下来解决id复用的问题,新建一个js或ts文件,对方法进行封装并导出引入.
新建createID.js文件
export function createId(){ return 'id' +Math.random() }
引入js文件
import { createId } from '../../../api/createId'
在父组件中传入配置项option,这儿一折线图为例
let lineTwo = reactive({ color: ['#0298DB', '#F59A23'], title: { text: '出院人次数', left: 80, top: 20, textStyle: { fontWeight: 400, fontFamily: 'Arial Normal', fontStyle: 'normal', fontSize: 20, color: '#555555' } }, grid: { top: 70, bottom: 40, }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, xAxis: { type: 'category', boundaryGap: false, data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'] }, yAxis: { type: 'value', show: true, min: 0, max: 5000, iterval: 1000, axisLine: { show: true }, axisLabel: { formatter: function (value, index) { return value >= 1000 ? parseInt(value / 1000) + '千' : value; } }, axisPointer: { type: 'shadow' } }, legend: { // itemStyle: {}, //继承系列中属性值的颜色 right: 80, top: 15, itemGap: 20, itemWidth: 9, itemHeight: 10, data: [ { icon: 'rect', name: '今年' }, { icon: 'rect', name: '去年' } ], textStyle: { fontWeight: 400, fontFamily: 'Arial Normal', fontStyle: 'normal', fontSize: 20, color: '#555555', } }, series: [ { name: '今年', symbol: 'none', data: [1500, 2300, 2240, 2180, 1350, 1470, 2600, 1110, 1230, 1450, 1680, 2360], type: 'line' }, { name: '去年', symbol: 'none', data: [1000, 1300, 2504, 3080, 1050, 1740, 2200, 2120, 1230, 1550, 1460, 1530], type: 'line' } ] })
在父组件中传值
<div class="atlas flex"> <charts :option="lineOne" :id="createId()" /> </div>
子组件通过difineprops接收父组件传过来的值
<template> <div :id="id"></div> </template>
let { id, option } = defineProps({ option: Object, id: String })
效果图:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。