使⽤Vue开发动态刷新Echarts组件的教程详解
需求背景:dashboard作为⽬前企业中后台产品的“门⾯”,如何更加实时、⾼效、炫酷的对统计数据进⾏展⽰,是值得前端开发⼯程师和UI设计师共同思考的⼀个问题。今天就从0开始,封装⼀个动态渲染数据的Echarts折线图组件,抛砖引⽟,⼀起来思考更多有意思的组件。
准备⼯作
项⽬结构搭建
因为⽣产需要(其实是懒),所以本教程使⽤了 ==vue-cli==进⾏了项⽬的基础结构搭建。
npm install -g vue-cli
vue init webpack vue-charts
cd vue-charts
npm run dev
安装Echarts
直接使⽤npm进⾏安装。
npm install Echarts --save
引⼊Echarts
//在main.js加⼊下⾯两⾏代码
import echarts from 'echarts'
Vue.prototype.$echarts = echarts //将echarts注册成Vue的全局属性
到此,准备⼯作已经完成了。
静态组件开发
因为被《React编程思想》这篇⽂章毒害太深,所以笔者开发组件也习惯从基础到⾼级逐步迭代。
静态组件要实现的⽬的很简单,就是把Echarts图表,渲染到页⾯上。
新建Chart.vue⽂件
<template>
<div :id="id" :></div>
</template>
<script>
export default {
name: "Chart",
data() {
return {
//echarts实例
chart: ""
};
},
props: {
//⽗组件需要传递的参数:id,width,height,option
id: {
type: String
},
width: {
type: String,
default: "100%"
},
height: {
type: String,
default: "300px"
},
option: {
type: Object,
//Object类型的prop值⼀定要⽤函数return出来,不然会报错。原理和data是⼀样的,
//使⽤闭包保证⼀个vue实例拥有⾃⼰的⼀份props
default() {
return {
title: {
text: "vue-Echarts"
},
legend: {
data: ["销量"]
},
xAxis: {
data: ["衬衫", "⽺⽑衫", "雪纺衫", "裤⼦", "⾼跟鞋", "袜⼦","tuoxie"]
},
series: [
{
name: "销量",
type: "line",
data: [5, 20, 36, 10, 10, 70]
}
]
};
}
}
},
computed: {
style() {
return {
height: this.height,
width: this.width
};
}
},
mounted() {
this.init();
},
methods: {
init() {
this.chart = this.$echarts.ElementById(this.id));
this.chart.setOption(this.option);
}
}
};
</script>
上述⽂件就实现了将⼀个简单折线图渲染到页⾯的组件,怎么样是不是很简单?最简使⽤⽅法如下:App.vue
<template>
<div id="app">
<Chart id="test"/>
</div>
</template>
<script>
import Chart from "./components/Chart";
export default {
name: "App",
data() {},
components: {
Chart
}
}
</script>
⾄此,运⾏程序你应该能看到以下效果:
第⼀次迭代
现在我们已经有了⼀个基础版本,让我们来看看哪些⽅⾯做的还不尽如⼈意:
1. 图表⽆法根据窗⼝⼤⼩进⾏⾃动缩放,虽然设置了宽度为100%,但是只有刷新页⾯图表才会重新进⾏渲染,这会让⽤
户体验变得很差。
2. 图表⽬前⽆法实现数据⾃动刷新
下⾯我们来实现这两点:
⾃动缩放
Echarts本⾝是不⽀持⾃动缩放的,但是Echarts为我们提供了resize⽅法。
//在init⽅法中加⼊下⾯这⾏代码
window.addEventListener("resize", size);
只需要这⼀句,我们就实现了图表跟随窗⼝⼤⼩⾃适应的需求。
⽀持数据⾃动刷新
因为Echarts是数据驱动的,这意味着只要我们重新设置数据,那么图表就会随之重新渲染,这是实现本需求的基础。我们再设想⼀下,如果想要⽀持数据的⾃动刷新,必然需要⼀个能够实时监听到数据的变化然后告知Echarts重新设置数据。所幸Vue为我们提供了==watcher==功能,通过它我们可以很⽅便的实现上述功能:
//在Chart.vue中加⼊watch
watch: {
//观察option的变化
option: {
handler(newVal, oldVal) {
if (this.chart) {
if (newVal) {
javascript动态效果this.chart.setOption(newVal);
} else {
this.chart.setOption(oldVal);
}
} else {
this.init();
}
},
deep: true //对象内部属性的监听,关键。
}
}
上⾯代码就实现了我们对option对象中属性变化的监听,⼀旦option中的数据有了变化,那么图表就会重新渲染。
实现动态刷新
下⼀步我想⼤家都知道了,就是定时从后台拉取数据,然后更新⽗组件的option就好。这个地⽅有两个问题需要思考⼀下:
1. 如果图表要求每秒增加⼀个数据,应该如何进⾏数据的请求才能达到性能与⽤户体验的平衡?
2. 动态更新数据的代码,应该放在⽗组件还是⼦组件?
对第⼀个问题,每秒实时获取服务器的数据,肯定是最精确的,这就有两种⽅案:
每秒向后台请求⼀次
保持长连接,后台每秒向前端推送⼀次数据
第⼀种⽅案⽆疑对性能和资源产⽣了极⼤的浪费;除⾮实时性要求特别⾼(股票系统),否则不推荐这种⽅式;
第⼆种⽅案需要使⽤web Socket,但在服务端需要进⾏额外的开发⼯作。
笔者基于项⽬的实际需求(实时性要求不⾼,且后台⽣成数据也有⼀定的延迟性),采⽤了以下⽅案:
1. 前端每隔⼀分钟向后台请求⼀次数据,且为当前时间的上⼀分钟的数据;
2. 前端将上述数据每隔⼀秒向图表set⼀次数据
关于第⼆个问题:笔者更倾向于将Chart组件设计成纯组件,即只接收⽗组件传递的数据进⾏变化,不在内部进⾏复杂操作;这也符合⽬前前端MVVM框架的最佳实践;⽽且若将数据传递到Chart组件内部再进⾏处理,⼀是遇到不需要动态渲染的需求还需要对组件进⾏额外处理,⼆是要在Chart内部做ajax操作,这样就导致Chart完全没有了可复⽤性。
接下来我们修改App.vue
<template>
<div id="app">
<Chart id="test" :option="option"/>
</div>
</template>
<script>
import vueEcharts from "./components/vueEcharts";
export default {
name: "App",
data() {
return {
//笔者使⽤了mock数据代表从服务器获取的数据
chartData: {
xData: ["衬衫", "⽺⽑衫", "雪纺衫", "裤⼦", "⾼跟鞋", "袜⼦"],
sData: [5, 20, 36, 10, 10, 70]
}
};
},
components: {
Chart
},
mounted() {
},
methods: {
//添加refreshData⽅法进⾏⾃动设置数据
refreshData() {
/
/横轴数据
let xData = this.chartData.xData,
//系列值
sData = this.chartData.sData;
for (let i = 0; i < xData.length; i++) {
//此处使⽤let是关键,也可以使⽤闭包。原理不再赘述
setTimeout(() => {
this.option.xAxis.data.push(xData[i]);
this.option.series[0].data.push(sData[i]);
}, 1000*i)//此处要理解为什么是1000*i
}
}
}
};
</script>
⾄此我们就实现了图表动态数据加载,效果如下图:
总结
这篇教程通过⼀个动态图表的开发,传递了以下信息:
Echarts如何与Vue结合使⽤
Vue组件开发、纯组件与“脏”组件的区别
Vue watch的⽤法
let的特性
JavaScript EventLoop特性
...
⼤家可以根据这个列表查漏补缺。
后续优化
1. 这个组件还有需要需要优化的点,⽐如:
2. 间隔时间应该可配置
3. 每分钟从后台获取数据,那么图表展⽰的数据将会越来越多,越来越密集,浏览器负担越来越⼤,直到崩溃
4. 没有设置暂停图表刷新的按钮
5. ...
总结
以上所述是⼩编给⼤家介绍的使⽤Vue开发动态刷新Echarts组件的教程详解,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。在此也⾮常感谢⼤家对⽹站的⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。