在vue下封装echarts公共组件的总结
这几天公司里边有一个项目,叫做日控制台,该项目是在webview下的一个webapp,使用vue构建,项目中要求使用许多自定义的图表。考察了许多图表组件之后,发现echarts是所有表库中,最灵活,特效最好看的一种。一、构建基础公共组件1。实现基础功能
在echart官网上搜索到,如何使用1。获取一个用于挂在echarts的DOM元素letechartsDOMdocument。getElementById(echartsdom)2。初始化letmyEchartsecharts。init(echartsDOM)3。设置配置项letoption{。。。}4。为echarts指定配置myEcharts。setOption(option)
使用echart的步骤也就这几部,就是先获取到承载echart实例的dom实例,然后调用init()方法初始化图标实例,最后调用setOption()方法传入配置项
这几步都要在vue的mounted方法下实现。mounted(){letechartsDOMdocument。getElementById(echartsdom)letmyEchartsecharts。init(echartsDOM)letoption{title:{text:ECharts入门示例},tooltip:{},legend:{data:〔销量〕},xAxis:{data:〔衬衫,羊毛衫,雪纺衫,裤子,高跟鞋,袜子〕},yAxis:{},series:〔{name:销量,type:bar,data:〔5,20,36,10,10,20〕}〕}myEcharts。setOption(option)}}
注:在Vue中,首先我们需要使用importechartsfromecharts以引入echarts。二、组件化
思路很简单,就是将业务上用到的图表,比如柱状图、折线图,通通封装成组件,然后再mainapp文件中调用,通过分析,可以通过传props,来改变setOption()方法中的对象,达到封装不同图表组件的目的。ocEchartsclassechartscontainer:optionsocoptions
将之前的options转移到mainapp中的data对象之中。
注:echarts图表要求承载的容器具有固定的宽高才能正常显示。echartscontainer{width:100;height:20rem;}1。组件优化props的series校验
如果在传入组件的props中传入了空对象,就会发现,图表会抛出一个错误,即
Error:Optionshouldcontainsseries。
原因就是传入的option配置对象不含有series键,所以,默认值处理是需要存在的,即当调用方传入的对象为空或不存在series配置时,应在页面上显示一些提示(对用户友好的提示,而不是对编程人员),即避免因报错而造成空白的情况。
此外,当我们像之前那样给option这一参数进行类型限制后,倘若调用方传入非对象类型,Vue会直接抛出错误这一结果也不是我们想要的。我们应该取消类型限制,并在option发生变化时进行依次以下判断:1。是否为对象;exportfunctionisObject(option){returnObject。prototype。isPrototypeOf(option)}2。是否为空对象;exportfunctionisEmptyObject(option){returnObject。keys(option)。length0}3。是否包含series键;exportfunctionhasSeriesKey(option){return!!option〔series〕}4。series是否为数组;exportfunctionisSeriesArray(option){returnArray。isArray(option〔series〕)}5。series数组是否为空。exportfunctionisSeriesEmpty(option){returnoption〔series〕。length0}exportfunctionisValidOption(option){returnisObject(option)!isEmptyObject(option)hasSeriesKey(option)isSeriesArray(option)!isSeriesEmpty(option)}
然后在组件中引入最后的isValidOption方法作为判断,我们先使用一个watch监听options的变化watch:{options(options){this。checkAndSetOption()}},methods:{checkAndSetOption(){letoptionsthis。optionsif(isValidOption(options)){this。myEcharts。setOption(options)this。isOptionAbnormalfalse}else{this。isOptionAbnormaltrue}}}
这里的checkAndSetOption方法是判断传入的option是否合法,如果合法,就执行setOption,isOptionAbnormal变量是监控页面是否显示options非法的flag。
同样的dom样式上的改变,也要使用vshow来判断isOptionAbnormal是否要渲染图表和渲染错误信息。数据为空。ocechartscontainer,。echarts{width:100;height:100;}。shadow{width:100;height:100;display:flex;justifycontent:center;alignitems:center;fontsize:1rem;color:8590a6;}2。增强组件功能数据加载提示数据加载中。。。
在组件内部需要一个外部的props,isLoading,但是这里需要注意,在Vue中,vshow使用display控制组件的显隐。而当echartinit的时候,如果其挂载DOM的vshow处于false状态,则其init的对象宽高都是0。即使之后vshow状态改变,由于mounted生命周期不会再次触发,从而使得echarts显示不正常。所以需要使用css的visibility来控制显隐。computed:{isChartVisible(){return!this。isLoading!this。isOptionAbnormal}},3。组件复用随机ID
echarts进行init挂载时使用的是DOM元素的ID。而在组件中,我们设置的ID是固定的(注意与scopedcss进行区分)。如果多个组件的ID是相同的,只有一个组件会被echarts挂载。
所以我们要设定一个随机的randomId,赋值到承载echarts图表的dom元素的id中三、延迟加载
延迟加载是组件的一个优化,在业务的开发中可以看到,一个页面往往有着许多的图表,图标伴随着许多异步请求和canvas渲染,如果一次性渲染所有的图表会导致许多的性能问题。这里想到的一个解决方案就是延迟加载。
用通俗的话讲就是,页面滚动到哪张图表就去渲染哪一张图表。
完成这一功能需要以下步骤:监听页面滚动事件;滚动事件中获取echarts的位置;在页面当前位置达到echarts位置的时候进行echarts的初始化。1。监听页面滚动
如果要监听页面滚动,需要用到dom的监听器,addEventListener(scroll,〔funciton〕)。这样就能为每一个组件附上监听事件。2。获取当前滚动下边界和组件的上边界
这一个步骤需要封装成一个函数,checkPosition()checkPosition(){letwindowHeightdocument。documentElement。clientHeightwindow。innerHeightletscrollTopdocument。documentElement。scrollTopdocument。body。scrollTopletwindowBottomscrollTopwindowHeightconstselfTop。get(this。refs,selfEcharts。offsetTop,0);if(windowBottomselfTop){this。isPositionReadytruethis。checkAndSetOption()window。removeEventListener(scroll,this。scrollEvent)}},windowBottom(滑动的下边界)scrollTop(屏幕当前滑动的距离)windowHeight(窗口的高度)selfTop(当前组件的顶部位置)
当第一个变量大于第二个变量时,就认为滑动到了该图表组件,就开开启加载3。初始化data(){return{myEcharts:null,isOptionAbnormal:false,randomId:echartsdomDate。now()Math。random(),scrollEvent:。throttle(this。checkPosition,500),滑动事件isPositionReady:false,控制数据异步与页面滚动先后顺序的flag}},mounted(){letechartsDOMdocument。getElementById(this。randomId)if(!echartsDOM)returnthis。myEchartsecharts。init(echartsDOM)第一次未滑动的时候this。checkPosition()滑动之后的监听window。addEventListener(scroll,this。scrollEvent)},
checkPosition方法不仅要在scroll监听事件中调用,在组件第一次渲染的时候也要调用一次进行初始化,不然,组件无法正常渲染图表。4。节流
组件代码经过测试之后发现,如果滚动过于快速,会不停的调用checkPosition(),关键是这个方法会不停的去setOption(),所以以上代码均采用了lodash的throttle节流方法,在500毫秒内只允许调用一次。5。解绑监听事件
解绑事件,组件中有设定监听器,如果该图表已经被加载了,那么这个监听器就没有作用了。window。removeEventListener(scroll,this。scrollEvent)
这段代码就是解绑监听器,多多少少会优化一下速度吧。因为增加监听和解绑监听的时间函数要求一致,所以在data中新增了scrollEvent,顺便把节流函数一起加了上去。6。请求异步控制setOption
由于用于渲染echarts的数据常常是异步获取的,也就是说,option可能会在异步调用结束之后更新,从而触发option的watch,进而导致this。checkOption()执行,最终使得setOption在页面没有滚动到合适位置时就触发了。
为了解决这个问题,我们应该让setOption的过程受制于一个标识位,而该标识位会在页面滚动到合适位置时置为true,从而杜绝由于option更新、触发watch而导致的漏洞。
首先,我们要添加一个新的data,取名为为isPositionReady,然后,在checkAndSetOption()中加入对该标识位的判断:最后,在位置检测方法checkPosition()中,当达到合适位置时,将该标识位置为truecheckPosition(){。。。。if(windowBottomselfTop){this。isPositionReadytrue。。。。}},checkAndSetOption(){。。。。if(!this。isPositionReady)return。。。。}四、echarts重绘
这里的重绘指的是ehcarts中的resize()方法。用于在某些时刻进行echarts的调整,包括:组件宽度设置为百分比,浏览器宽度发生变化时;页面收缩元素状态改变,如侧边栏收缩导致内容区宽度变化;1。页面宽度改变
继续增加监听器就能完成window。addEventListener(resize,。throttle((){this。myEcharts。resize()console。log()},500))
我带上钱你带上我,一起去云南吧头条创作挑战赛今年的夏天,虽然已经过去,可是却给我留下了最热的印象,活了30年了,以前小时候家里穷,就算夏天没有风扇,白天再热一把扇子摇两下也就过了,可现在只能整天待在空调房里,今
去新疆,来一次摆烂式旅行!(原创)最近网络上有一个新名词摆烂式旅行,咋一看有点莫名其妙,这是做哪样?仔细阅读了几篇摆烂式旅行的游记和攻略,这才恍然大悟。它的基本含义是不一定要去那些知名热门景点,或者去追赶所谓的最佳
新疆拌面,西出阳关最劳道的拉条子秋日生活打卡季这个子,那个子,天天离不开拉条子,一天不吃拉条子,好象个霜打的蔫茄子。酸菜拌面酸菜拉条子是新疆拌面俗称,维吾尔语叫兰格曼。北疆习惯称拉条子,南疆多称拌面。无论是新疆的
21!曼城3次挑落多特,哈兰德追赶姆巴佩,小心9000万球星北京时间10月26日,欧冠小组赛第5轮将打响一场焦点战,多特蒙德主场迎战曼城。赛前,曼城积10分已提前出线,多特蒙德积7分排名小组第2。这场比赛对于曼城和多特都非常重要,前者要竞争
晒晒太阳就能发电的伞你见过吗?松江企业研发的户外智享伞伞亮登场普通的伞是用来遮蔽雨雪光等的工具,而由伞亮(上海)智能科技有限公司研发的被昵称为小伞同学的太阳能多功能户外智享伞,则通过晒晒太阳就能轻松把太阳能转化为电能储存起来,在拥有高颜值的同
很多女性为什么不化妆都不敢出门?看完后,请直面真正的自己很多女性为什么不化妆都不敢出门?看完后,请直面真正的自己!与过去相比,当代年轻女性发生了巨大的变化。越来越多的女孩想要有一个良好的外部形象,尤其是在与陌生人或异性交流时。他们希望给
科普逍遥丸,更年期女性可以长期用吗?50岁的张女士闭经半年,近期失眠潮热症状明显,服用逍遥丸有所改善,于是便打算长期服用。张女士这样长期吃逍遥丸可以吗?逍遥丸来源于宋代太平惠民和剂局方,是从伤寒论四逆散演变而来。成分
骂醒你的励志文案!!!(年轻人多看看)1要么努力往上爬,要么烂在社会最底层。2你现在的努力,真的配得上你的野心吗?3承认吧你表面的不屑,只是因为你骨子里的不敢。4你说我现在开始好好学,晚了吗?我说晚了,你就不学吗???
爱博医疗2022年前三季度净利润1。99亿元同比增长41。82中证智能财讯爱博医疗(688050)10月26日披露2022年第三季度报告。2022年前三季度,公司实现营业总收入4。41亿元,同比增长35。83归母净利润1。99亿元,同比增长4
希望你能有一个好心情当我讨厌一个人的时候,如果这个人突然说喜欢我,那我就一点也不讨厌对方了。就是这么有原则,无法讨厌一个有眼光的人。假如生活欺骗了你,不要着急,拿出美颜相机,去欺骗生活。主动加你的女性
我们走着走着失去了光头条创作挑战赛脸上有微笑,心里有阳光,眼里有风景,抬头所见皆是温柔。抖音里一段短视频,入耳大风吹,我一连看了几遍,莫名地落下了眼泪。我只是觉得有些心酸,似乎我曾经脸上也时常挂着微笑
党的二十大代表李胜紧抓机遇,发挥智慧水利更大作用来源中国经济网中国经济网北京10月21日讯(记者李方)聆听二十大报告,我倍感振奋!对实现中华民族伟大复兴,我充满信心!党的二十大代表,来自水利行业的贵州东方世纪科技股份有限公司党支
加速布局ESG领域绿色金融类理财产品发行升温来源中国证券报目前,工银理财首只ESG主题理财产品鑫悦ESG优选私银尊享固收增强封闭式理财产品已开始募集。此外,9月末,恒丰理财推出扬帆起航恒惠绿色金融封闭式理财产品,首发当日销售
工伤认定后,由谁赔偿?职工在工伤认定后,应该由谁来赔偿?一起跟随记者了解一下。如果单位缴纳了工伤保险,由工伤保险基金和单位共同赔偿若单位没有缴纳工伤保险,由单位承担所有赔偿。法律依据社会保险法第四十一条
深化对口援助激发内生力量深化民生援助成果,让群众更有获得感,最终还是要激发被支援地方的内生动力,实现跨越式可持续发展前段时间,在西藏自治区林芝市米林县援藏的一名医生突发急性心脏病,林芝市胸痛中心开通绿色通
十月新番开播近一个月,安利几部少有人关注的冷门番不知道是不是最近摸鱼太多的原因,总感觉这个十月过得有点快。印象中十一假期才刚结束,可看了日期才发现已经到20号了。趁着十月还在,像以往的几个新番季一样,继续来给大家做一期冷门新番的
急!急!急!儿童急性感染性腹泻药知道作者暨南大学附属广州红十字会医院药师王靖儿童急性感染性腹泻病是什么?指病程在2周以内由病原微生物感染引起的腹泻病。急性感染性腹泻病发病率高流行广泛,严重危害儿童健康。儿童急性感染性
90后女孩,为做单身孕妈买精生子,不要世俗婚姻只做独立女性单身孕妈,这是近些年,一个非常前卫的新称呼!指的是那些不结婚,通过人工受孕怀上孩子的女性。孩子出生后,由妈妈一手抚养大,全程无父亲参与,因此在孩子出生后,这也被叫做丧偶式育娃。配图
浅谈孕双胎经历双胎竟然也分好几种经历了一系列资料的查询,才发现双胎原来也分好几种。同卵双胎和异卵双胎,同卵双胎又分两种。一双绒双羊有两个胎盘,龙凤胎的几率大概百分之二十五,这个是最安全的一种双胞胎类型,相当于是两
养儿难先说说我吧,我的儿子从在我肚子里,就很不老实,5个月前孕吐吐到我住院安胎,从早打到晚的营养针,被针扎过得地方很黑,就用热水敷,两只手轮着打,那时候疼到哭,差点就想打掉了,6个多月开
必看!这些食物打死也不能让宝宝吃宝宝从出生开始,每一口食物都很关键,给宝宝准备食物,那更是艰巨的任务。科学营养是目标,食品安全是第一位,千万要记得这个原则大人不能吃的,宝宝绝对不能吃!大人能吃的,宝宝不一定能吃!
带娃妈妈最讨厌听到的十句话每个带娃的妈妈都应当被理解,被照顾。带娃不仅仅是妈妈的责任,爸爸也是不可或缺的角色。作为家人尽可能要体谅带娃妈妈的心情,不要轻易说出伤人的话1。你奶水不够就去追奶啊,奶粉没营养。2