Vue 2.x折腾记 - 写一个挺不靠谱的Vue-Echarts组件
Posted crper
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 2.x折腾记 - 写一个挺不靠谱的Vue-Echarts组件相关的知识,希望对你有一定的参考价值。
前言
上基友社区看了下,发现对echarts的封装都是打包进去的,想想就还是算了。
图表这货.说实在的,若不是整个系统大量用到,打包进去没必要。
CDN是个好东西,我们完全可以写一个异步加载JS然后封装按需调用。
至于你能学到什么,见仁见智了,若有所收获就是我这文章的意义所在了 。
效果图
实现思路及实现的功能
- 异步引入
echarts
,有三个版本,不是最大也不是最小那个,具体上官网看 - 图表的销毁释放内存
- 图表跟随父包含块自适应(事件监听)
setOption
的抽离,图表实例化id
随机生成或者手动传入setOption
可以一次性传入整个图表的参数,也可以拆分传入(太多,只选了几个复用率很高选项的)…都设置了默认值.- 随机
id
是大写字母的组合,外部有传入则用外部的
代码
实现Vue.use(?)
index.js – 导出组件的,内部实在亮瞎眼
import echarts from "./echarts";
// Vue.use必须有install这个函数..可能我这里写的比较粗糙..有兴趣的可以去完善
// 用是可以正常使用的
export default
install: function(Vue, Option)
Vue.component("vue-echarts", echarts);
;
echarts.vue
<template>
<div class="vue-echarts" :id="id" :style="style">
</div>
</template>
<script>
export default
name: 'vue-echarts',
data: function ()
return
loadJS: '', // 存储异步加载echart的promise状态
chart: '', // 保存地图初始化的实例
,
props:
id:
type: String,
default: function () // 生成一个随机字符串,纯英文的,当不传入ID的时候生成实例,加i确保不会随机到一样的
let temp = [];
for (let i = 0; i < 6; i++)
let randomChar = String.fromCharCode(65 + Math.floor(Math.random() * 19) + i);
temp.push(randomChar);
return temp.reduce((pre, next) => pre + next);
,
height: // 图表高度
type: String,
default: '300px'
,
width: // 图表宽度
type: String,
default: '100%'
,
legend: // 以下的配置都是echarts官方图表的自定义部分,我拆分这么几大块
type: Object,
default: function ()
return
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
,
title:
type: Object,
default: function ()
return
text: '堆叠区域图'
,
tooltip:
type: [Array, Object],
default: function ()
return
trigger: 'axis',
axisPointer:
type: 'cross',
label:
backgroundColor: '#6a7985'
,
animation: true
,
toolbox:
type: Object,
default: function ()
return
show: true,
feature:
dataZoom:
yAxisIndex: 'none'
,
dataView: readOnly: false ,
magicType: type: ['line', 'bar'] ,
restore: ,
saveAsImage:
,
grid:
type: Object,
default: function ()
return
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
,
xAxis:
type: [Array, Object],
default: function ()
return [
type: 'category',
boundaryGap: true,
data: ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00']
]
,
yAxis:
type: [Array, Object],
default: function ()
return [
type: 'value'
]
,
series:
type: [Array, Object],
default: function ()
return [
name: '曝光',
type: 'line',
smooth: true,
lineStyle:
normal:
color: '#f00',
,
data: [120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 134, 90, 120]
,
name: '点击',
type: 'line',
smooth: true,
lineStyle:
normal:
color: '#20a0ff',
,
data: [220, 182, 191, 234, 290, 330, 310, 120, 132, 101, 134, 90, 120]
,
name: '点击率',
type: 'line',
lineStyle:
normal:
color: '#42b983',
,
smooth: true,
data: [150, 232, 201, 154, 190, 330, 410, 120, 132, 101, 134, 90, 120]
]
,
setOption:
type: Object
,
dispose: Boolean
,
computed:
style ()
return
height: this.height,
width: this.width
,
created ()
this.loadJS = this.loadEchartsJS();
,
mounted ()
this.loadJS.then(() =>
let st = setTimeout(() =>
this.init(); // CDNJS加载后,元素渲染后,初始化图表
, 300);
).catch(err =>
console.log('echarts js加载失败');
);
,
beforeDestroy ()
window.removeEventListener('resize', this.chart.resize)
if (this.chart)
this.chart.dispose(); // 销毁图表实例
,
methods:
init () // 初始化图表
this.chart = new echarts.init(document.getElementById(this.id));
this.chart.setOption(this.setOption);
window.addEventListener('resize', this.chart.resize) // 图表响应大小的关键,重绘
,
loadEchartsJS () // 异步请求cdnjs
const CDNURL = 'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js';
return new Promise((resolve, reject) =>
const script = document.createElement('script');
script.type = "text/javascript";
script.id = "cdnEchart";
if (script.readyState) //IE
script.onreadystatechange = function ()
if (script.readyState == "loaded" ||
script.readyState == "complete")
script.onreadystatechange = null;
resolve('success: ' + CDNURL);
;
else //Others
script.onload = function ()
resolve('success: ' + CDNURL);
;
script.onerror = function ()
reject(Error(CDNURL + 'load error!'));
;
script.src = CDNURL;
if (!document.getElementById('cdnEchart'))
document.head.appendChild(script);
);
,
watch:
setOption:
handler: function (newVal, oldVal) // 监听外部传入的值,渲染新的的图表数据
if (this.chart)
if (newVal)
this.chart.setOption(newVal);
else
this.chart.setOption(oldVal);
this.chart.resize();
else
setTimeout(() =>
this.init();
, 300);
,
deep: true
</script>
如何使用
- main.js – 主入口文件,
// promise的polyfill
require("es6-promise").polyfill();
// 百度图表
import echarts from './components/common/echarts';
Vue.use(echarts);
总结
好吧,写这个东西花了一下午的时间,从构思到去查echarts api
到实现;
粗糙的版本已经诞生,可能还有可以优化的地方,只能待我以后发现了再做调整了.
有更好的实现方案和思路的可以往下面留言。
以上是关于Vue 2.x折腾记 - 写一个挺不靠谱的Vue-Echarts组件的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 + 折腾记 : 动手写一个不怎么靠谱的上传组件
vue-elementUi-Calendar前端日历插件折腾记