当前位置: 首页 > Web前端 > vue.js

记录一个Vue组件封装过程

时间:2023-03-31 20:34:48 vue.js

简介在开发前端项目的过程中,需要展示大量的图表数据。为了方便使用和代码复用,基于ECharts封装了各种图表组件。直接使用封装好的组件对刚接触我们项目的人来说会更加友好,了解组件的封装思路和封装细节,有助于我们在实践中更加熟练地使用组件。本文将以雷达图为例,一步步讲解如何在vue项目中使用ECharts,以及如何将其封装为可重复调用的组件。在准备工作开始之前,我们按照正常的组件注册流程,在项目的components目录下新建一个名为radar-chart的组件,然后在一个Demo页面导入该组件。新建雷达图组件内容://radar-chart.vue(subcomponent)演示页面代码://demo.vue(父组件)Demo页面效果图1:初始化图表准备完成后,我们要做的就是引入ECharts,并在组件中初始化一个ECharts的实例。这里我们可以从官网复制实例和数据。(1)在radar-chart.vue中引入ECharts://radar-chart.vue(subcomponent)importechartsfrom'echarts';(2)methods中创建图表配置数据方法,数据格式参考Echarts官网://radar-chart.vue(subcomponent)methods:{//初始化图表配置initOption(){letvm=this;vm.option={title:{text:'BasicRadarChart'},tooltip:{},legend:{data:['AllocatedBudget','ActualSpending']},radar:{//形状:'circle',name:{textStyle:{color:'#fff',backgroundColor:'#999',borderRadius:3,padding:[3,5]}},indicator:[{name:'sales',max:6500},{name:'Administration',max:16000},{name:'信息技术(我informationTechnology)',max:30000},{name:'客户支持(CustomerSupport)',max:38000},{name:'开发(Development)',max:52000},{name:'Marketing(营销)',max:25000}]},series:[{name:'预算与支出(Budgetvsspending)',type:'radar',//areaStyle:{normal:{}},data:[{value:[4300,10000,28000,35000,50000,19000],name:'AllocatedBudget'},{value:[5000,14000,28000,31000,42000,21000],name:'实际支出'}]}]};},},(3)初始化图表:在组件hook挂载方法中://radar-chart.vue(subcomponent)mounted(){this.initOption();this.$nextTick(()=>{//这里的$nextTick()方法是在下一个DOM更新周期结束后执行延迟回调也就是延迟渲染图表,避免一些渲染问题this.ready();});},在方法中://radar-chart.vue(subcomponent)ready(){letvm=this;让dom=document.getElementById('雷达图');vm.myChart=echarts.init(dom);vm.myChart&&vm.myChart.setOption(vm.option);}、Demo页面效果图2:这里分三步,介绍ECharts,初始化图表配置,初始化图表,最后在Demo页面就可以看到了,ECharts的雷达图已经初步展示在项目中了。提取图表配置属性(重点)上面我们已经成功创建了雷达图,但是很明显radar-chart.vue中的数据是硬编码的,不能重复调用。接下来要做的就是包装。封装的思路是这样的:demo.vue传递一组个性化数据给radar-chart.vueradar-chart.vue接收数据通过props选项细化接收到的数据,覆盖配置数据选项初始化图表。传递数据,在data中定义变量,在mounted中赋值//demo.vue(父组件)从props中的父组件接收数据//radar-chart.vue(subcomponent)props:{//指标数据,必填项//格式示例[{name:'a',max:1},{name:'a',max:1},{name:'a',max:1}]指标:{type:Array,default:()=>[]},//图例数据,必填//格式示例[{value:[5000,14000,28000],name:'name'},{value:[5000,14000,28000],name:'name'}]legendData:{type:Array,default:()=>[]},},**在ready()中更新图表数据选项如果在这里更新了指标和数据的两个属性值,则不需要在这两个值中初始化initOption()**//radar-chart.vue(subcomponent)ready(){letvm=this;让dom=document.getElementById('雷达图');vm.myChart=echarts.init(dom);//获取指标数据vm.option.radar.indicator=vm.indicator;//获取图例数据vm.option.series[0].data=vm.legendData;vm.myChart&&vm.myChart.setOption(vm.option);},Demo页面渲染三:细节优化等注意事项以下代码是在完成代码的基础上修改添加的1.当一个页面有多个图表时,自动生成图表ID。实现原理可以参考ES6模块化和.vue组件的应用实例。补充代码://radar-chart.vue(子组件)2.图表数据属性通过props接收,图表默认配置属性通过defaultConfig保存,父组件传入的配置属性chartConfig通过$attrs直接获取,最后合并到finallyConfig供使用,便于扩展和维护。补充代码://radar-chart.vue(subcomponent)3.使用watch进行监控图表数据更新//radar-chart.vue(subcomponent)watch:{legendData(){this.$nextTick(()=>{this.ready();});}},4.添加窗口调整大小事件和图表点击事件//radar-chart.vue(subcomponent)exportdefault{data(){return{chartResizeTimer:null,//定时器,用于限制调整大小事件函数};},methods:{ready(){//添加窗口调整大小事件window.addEventListener('调整大小',vm.handleChartResize);//触发父组件的@chartClick事件vm.myChart.on('click',function(param){vm.$emit('chartClick',param);});},//处理窗口调整大小事件handleChartResize(){letvm=this;清除超时(vm.chartResizeTimer);vm.chartResizeTimer=setTimeout(function(){vm.myChart&&vm.myChart.resize();},200);},},beforeDestroy(){//释放图例资源,减少页面卡顿if(this.myChart)this.myChart.clear();//删除窗口调整大小事件window.removeEventListener('resize',this.handleChartResize);}};