vue-按需加载引用echarts中组件

目录

第一步:引用echarts组件库

第二步:main.js中全局配置主模版

第三步:封装echarts折线图line组件

第四步:在需要使用页面中引用line组件。


项目中我们一般会全局引用echarts组件库,开发起来方便。发现项目文件体积过大,首屏加载也会慢。为了解决首屏加载速度问题,项目体积大的问题。方法1:这就要求我们要采用按需加载的模式。没有使用到的echarts中组件不要引入项目中。方法2:路由采用懒加载的模式也会节省首屏加载时间。下面就是echarts折线图按需加载例子。

第一步:引用echarts组件库

命令:npm install echarts   ,命令:yarn add echarts

第二步:main.js中全局配置主模版

应用场景1:如果多个页面都需要使用echarts的图表,建议在main.js全局配置echats核心主模块,该模块是管理图表初始化,渲染的。

应用场景2: 如果使用图表的地方不多,可以不在main.js中引用主模块。也可以在封装的折线图组件中引用主模块。

/**
 * @file 项目主入口
 * @author yizuodao
 */

import Vue from 'vue'
import App from './App'
import router from './router'
// plugins
import echarts from 'echarts/lib/echarts'
Vue.prototype.$echarts = echarts

/* eslint-disable */
new Vue({
    el: '#app',
    router,
    store,
    components: { App },
    template: '<App/>'
})

第三步:封装echarts折线图line组件

功能点:

  • 设置折线图点击事件
  • 默认情况全部可以取消选中状态,我们想要折线图图例至少选中一个。
<template>
    <div class="module-container" :style="{width:width}">
        <div
            :id="lineId"
            class="module-body bg"
            :style="{height:height,width:width}">
        </div>
    </div>
</template>
<script>
// 按照使用到的功能添加组件导入,
require('echarts/lib/chart/line') // 按需导入折线组件
require('echarts/lib/chart/effectScatter') // 拐点出闪烁,高亮
require('echarts/lib/component/tooltip') // 提示组件
require('echarts/lib/component/legend') // 图例组件
require('echarts/lib/component/markPoint') // 标注组件
require('echarts/lib/component/markLine')
import 'zrender/lib/svg/svg' // svg模式

export default {
    name: 'info-Line',
    props: {
        lineId: { // 折线图图表id
            type: String,
            default() {
                return 'line'
            }
        },
        height: { // 折线图高
            type:String,
            default() {
                return '100%'
            }
        },
        width: { // 折线图宽
            type: String,
            default() {
                return '300px'
            }
        },
        option: { // 折线图配置
            type: Object,
            required: true // 数据
        },
        loading: { // 图形加载
            type: Boolean,
            default() {
                return false
            }
        },
        enabledClick: { // 折线图是否配置点击事件
            type: Boolean,
            default: false
        },
        optRenderer: { // 渲染模式:canvas,svg
            type: String,
            default() {
                return 'svg'
            }
        },
    },
    data() {
        return {
            line: null,
            empty: false,
        }
    },
    computed: {
        lineOption() {
            return this.option.series
        },
        pieToolInfoStatus() {
            let arr = Object.keys(this.toolInfo)
            if (arr.length > 0) {
                return true
            }
            return false
        },
        opts() {
            return {
                renderer: this.optRenderer,
            }
        },
    },
    watch: {
        lineOption() {
            this.option.series.length === 0 ? this.empty = true : (this.option.series[0].data.length === 0 ? this.empty = true : this.empty = false)
            if (this.empty) {
                this.line.clear()
                this.option.yAxis.data = []
                this.option.xAxis.data = []
                this.line.setOption(this.option)
            } else {
                this.drawLine()
            }
        },
    },
    mounted() {
        if (this.line === null) {
            this.line = this.$echarts.init(document.getElementById(this.lineId), null, this.opts)
        }
        /**
         * 设置折线图点击事件
         */
        if (this.enabledClick) {
            this.line.getZr().on('click', (params) => {
                let pointInPixel = [params.offsetX, params.offsetY]
                if (this.line.containPixel('grid', pointInPixel)) {
                    let pointInGrid = this.line.convertFromPixel({ seriesIndex: 0 }, pointInPixel)
                    let xIndex = pointInGrid[[0]]
                    let op = this.line.getOption()
                    let xValue = op.xAxis[0].data[xIndex]
                    this.$emit('onDetail', xValue, op.series[1].data[xIndex].groupTime)
                }
            })
        }
        /**
         * 设置图例最少一个选中
         */
        this.line.on('legendselectchanged', params => {
            let legendObj = params.selected
            let selectedNum = 0
            for (const key in legendObj) {
                if (legendObj.hasOwnProperty(key)) {
                    const element = legendObj[key]
                    if (element) {
                        selectedNum += 1
                    }
                }
            }
            if (selectedNum === 0) {
                legendObj[params.name] = true
                this.option.legend.selected = legendObj
                this.line.setOption(this.option)
            }
        })
    },
    beforeDestroy() {
        if (this.line !== null && this.line !== '' && !(typeof this.line === 'undefined')) {
            this.line.clear()
        }
    },
    methods: {
        /**
         * 折线图
         */
        drawLine: function() {
            if (this.line === null && this.line !== '' && !(typeof this.line === 'undefined')) {
                this.line = this.$echarts.init(document.getElementById(this.lineId), null, this.opts)
            }
            this.line.setOption(this.option)
        },
    }
}
</script>

第四步:在需要使用页面中引用line组件。

<template>
    <section class="section-body">
        <info-line
            :id="'timeLine'"
            :loading="timeLoading"
            :optRenderer="'canvas'"
            :option="timeLineOption">
        </info-line>
     </section>
</template>
<script>
import infoLine from '@/components/line'

export default {
    name: 'dataInfo',
    components: {
        infoLine,
    },
    data() {
        return {
            timeLineOption: {},
            timeLoading: false,
        }
    },
    mounted() {
        this.setLineOption()
    },
    methods: {
        setLineOption() {
            this.timeLineOption = {
                xAxis: {
                    type: 'category',
                    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    data: [820, 932, 901, 934, 1290, 1330, 1320],
                    type: 'line'
                }]
            }
        },
    }
}
</script>

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值