Vue项目中的Echarts实现异步加载
在项目中,首屏用到了echarts插件,类库精简,Gzip打包后也有100多K,如果在index.html里就开始加载echarts.js,也会造成1秒左右的阻塞时间
然而图表本身依赖ajax异步获取的数据,展示时需要时间的,没有必要在页面刚进入时候就把echarts加载完
所以最好的方式是在Vue中实现echarts的异步载入使用,哪里要用到哪里再开始加载,然后也就有了下面这段JS
echartsHelper.js
import appInfo from "../config/";
//appInfo.echartsUrl是echarts.js的网络地址
//appInfo.echartsIsReady是echarts.js是否加载完毕的标识位
const checkReady = () => {
return new Promise((resolve, reject) => {
const doCheck = () => {
setTimeout(() => {
appInfo.echartsIsReady ? resolve() : doCheck()
}, 1000)
}
doCheck();
});
}
export default {
asyncLoad() {
return new Promise((resolve, reject) => {
let hasInit = document.getElementById('EchartsJS')
if (hasInit) {
if (appInfo.echartsIsReady) {
resolve()
} else {
checkReady(id).then(() => {
resolve()
})
}
return
}
// 插入script脚本
let scriptNode = document.createElement("script");
scriptNode.setAttribute("id", "EchartsJS")
scriptNode.setAttribute("type", "text/javascript");
scriptNode.setAttribute("src", appInfo.echartsUrl);
document.body.appendChild(scriptNode);
// 等待页面加载完毕回调
scriptNode.onload = function () {
appInfo.echartsIsReady = true;
resolve()
}
scriptNode.onerror = function () {
reject()
}
});
},
}
在实际使用中,注释index.html中的echarts.js
index.html
<body>
....
<!-- <script src="xxx/echarts.min.mb.js"></script> -->
</body>
###在组件中使用
在组件中调用 echarts.init()
的地方调用
drawEcharts.vue
<template>
<!-- echarts图表 -->
<div class="line" ref="line"></div>
</template>
<script>
import echartsHelper from "../util/echartsHelper";
export default {
created() {
echartsHelper.asyncLoad().then(() => {
echarts.init(this.$refs.line);
});
}
}
</script>
然后就能看到echars在页面渲染后再加载了.
在页面中使用
在实际使用过程中,echars也可能被做成各类组件.并且包含了watch computed
之类的观察属性.
这时候echartsHelper.js也可以在父组件的生命周期的created里使用,这时候最好配合一个v-if标识位,防止组件自身在echarts被加载完毕前就被渲染导致的报错.
page.vue
<template>
<!-- echarts图表 -->
<div>
<!-- 组件加上标识位 -->
<v-echarts v-if="echartsIsLoad">
</div>
</template>
<script>
import echartsHelper from "../util/echartsHelper";
export default {
data(){
return {
echartsIsLoad:false //标识位
}
},
created(){
echartsHelper.asyncLoad().then(() => {
this.echartsIsLoad=true
....
});
}
}
</script>