Vue Web开发(七)

1. echarts介绍

echarts官方文档

首先我们先完成每个页面的路由,之前已经有home页面和user页面,缺少mail页面和其它选项下的page1和page2页面。在view文件夹下新建mail文件夹,新建index.vue,填充user页面的内容即可。在view下新建other文件夹,新建pageOne.vue和pageTwo.vue,页面内容简单填充即可。三个页面都要更改name属性,后面会用到,首字母大写。

cnpm i echarts@5.1.2安转指定版本依赖,在饼图的位置添加div,不需要在main.js中引入,只需要在home下的index.vue无版本引入。

(1)引入echarts

javascript 复制代码
import * as echarts from 'echarts'

(2)展示echarts饼图

javascript 复制代码
<el-card style="height:280px;">
  <div style="height:280px" ref="echarts"></div>
</el-card>

(3)更改mounted(){},data下包含四个图的数据,注意orderData下的第一个数据是date!!报错一直找不到是这个原因。这里用Object.keys()返回数组的属性而不包含属性值。keyArray就是一个key的集合(图例集合、数组属性集合),所以此处进行遍历。legend表示图例,就是keyArray。

javascript 复制代码
  mounted() {
            getData().then(res => {
                const {code, data} = res.data
                if (code === 20000) {
                    this.tableData = data.tableData
                    const order = data.orderData
                    const xData = order.date
                    const keyArray = Object.keys(order.data[0])
                    const series = []
                    keyArray.forEach(key => {
                        series.push({
                            name: key,
                            data: order.data.map(item => item[key]),
                            type: 'line'
                        })
                    })
                    const option = {
                        xAxis: {
                            data: xData
                        },
                        yAxis: {},
                        legend: {
                            data: keyArray
                        },
                        series:series
                    }
                    const myEcharts = echarts.init(this.$refs.echarts)
                    myEcharts.setOption(option)
                }
            })
        }

1.1. 折线图实现

将type改为line

javascript 复制代码
  mounted() {
            getData().then(res => {
                const {code, data} = res.data
                if (code === 20000) {
                    this.tableData = data.tableData
                    const order = data.orderData
                    const xData = order.date
                    const keyArray = Object.keys(order.data[0])
                    const series = []
                    keyArray.forEach(key => {
                        series.push({
                            name: key,
                            data: order.data.map(item => item[key]),
                            type: 'bar'
                        })
                    })
                    const option = {
                        xAxis: {
                            data: xData
                        },
                        yAxis: {},
                        legend: {
                            data: keyArray
                        },
                        series:series
                    }
                    const myEcharts = echarts.init(this.$refs.echarts)
                    myEcharts.setOption(option)
                }
            })
        }

效果图

1.2. 柱状图实现

src/views/home下的index.js。

javascript 复制代码
 <el-card class="graph-item1" >
                    <div style="height:210px" ref='barEchartRef'></div>
                </el-card>

mounted进行数据添加

javascript 复制代码
             //柱状图
                    const userOption = {
                        legend: {
                            // 图例文字颜色
                            textStyle: {
                                color: "#333",
                            },
                        },
                        grid: {
                            left: "20%",
                        },
                        // 提示框
                        tooltip: {
                            trigger: "axis",
                        },
                        xAxis: {
                            type: "category", // 类目轴
                            data: data.userData.map(item=>item.date),
                            axisLine: {
                                lineStyle: {
                                    color: "#17b3a3",
                                },
                            },
                            axisLabel: {
                                interval: 0,
                                color: "#333",
                            },
                        },
                        yAxis: [
                            {
                                type: "value",
                                axisLine: {
                                    lineStyle: {
                                        color: "#17b3a3",
                                    },
                                },
                            },
                        ],
                        color: ["#2ec7c9", "#b6a2de"],
                        series: [
                            {
                                name:'新增用户',
                                data:data.userData.map(item=>item.new),
                                type:'bar'
                            },
                            {
                                name:'活跃用户',
                                data:data.userData.map(item=>item.active),
                                type:'bar'
                            }
                        ],
                    }
                    const barEchart = echarts.init(this.$refs.barEchartRef)
                    barEchart.setOption(userOption)

效果图

1.3. 饼图实现

原理其实跟柱状图一样,知识柱状图条件会多一些。

javascript 复制代码
 const picOption = {
                        title: {//标题
                            subtext: "",
                            text: "饼图数据统计",
                            top: 'top',
                            left: 'center',
                            textStyle: {
                                fontSize: 11,
                            }
                        },
                        legend: {
                            itemHeight: 8,
                            itemWidth: 8,
                            // type: 'scroll',
                            orient: 'horizontal', // vertical
                            x: 'center',//可设定图例在左、右、居中
                            y: 'bottom',//可设定图例在上、下、居中
                            // padding:[0,50,0,0],//可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                            data: data.videoData,
                            //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                            // diamond:菱形 pin:水滴  arrow:箭头
                            icon: 'rect',
                        },
                        tooltip: {//弹出框
                            //trigger:触发类型,'item'数据项图形触发,主要在散点图,
                            // 饼图等无类目轴的图表中使用。'axis'坐标轴触发,主要在柱状图,
                            // 折线图等会使用类目轴的图表中使用。
                            trigger: 'item',
                            //triggerOn:提示框触发的条件,'mousemove'鼠标移动时触发。
                            // 'click'鼠标点击时触发。'mousemove|click'同时鼠标移动和点击时触发。
                            // 'none'不在 'mousemove' 或 'click' 时触发
                            //triggerOn:"mousemove",
                            //是否显示提示框浮层
                            //showContent:true,
                            //是否永远显示提示框内容
                            //alwaysShowContent:false,
                            //浮层显示的延迟,单位为 ms
                            //showDelay:0,
                            //浮层隐藏的延迟,单位为 ms
                            //hideDelay:100,
                            //鼠标是否可进入提示框浮层中
                            //enterable:false,
                            //是否将 tooltip 框限制在图表的区域内
                            confine: true,
                            //提示框浮层的移动动画过渡时间,单位是 s,设置为 0 的时候会紧跟着鼠标移动
                            //transitionDuration:0.4,
                            //提示框浮层的位置,默认不设置时位置会跟随鼠标的位置,[10, 10],回掉函数,
                            // inside鼠标所在图形的内部中心位置,top、left、bottom、right
                            // 鼠标所在图形上侧,左侧,下侧,右侧,
                            //position:['50%', '50%'],
                            //提示框浮层内容格式器,支持字符串模板和回调函数两种形式,
                            // 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等
                            //formatter:"{b0}: {c0}<br />{b1}: {c1}",
                            // formatter: '{a} <br/>{b}: {c} ({d}%)'
                            formatter: '{b} <br/> {c}件({d}%)',
                            //标题背景色,
                            //backgroundColor:"white",
                            //边框颜色
                            //borderColor:"#ccc",
                            //边框线宽
                            //borderWidth:0,
                            //图例内边距,单位px  5  [5, 10]  [5,10,5,10]
                            padding: 4,
                            //textStyle:文本样式
                            textStyle: {
                                fontSize: 10,
                            }
                        },
                        series: [
                            {
                                name: '统计分析',
                                type: 'pie',
                                clickable: true,//是否开启点击
                                minAngle: 2,//最小的扇区角度(0 ~ 360),防止某个值过小导致扇区太小影响交互
                                avoidLabelOverlap: true,//是否启用防止标签重叠策略
                                hoverAnimation: true,//是否开启 hover 在扇区上的放大动画效果。
                                silent: false,//图形是否不响应和触发鼠标事件
                                radius: ['30%', '50%'],//扇形环宽度
                                center: ['50%', '50%'],
                                labelLine: {
                                    normal: {
                                        length: 10, //第一条线
                                        length2: 8, //第二条线
                                        lineStyle: {
                                            width: 1, // 线条的宽度
                                            //线的颜色设置,如没有设置颜色则线条的颜色跟随饼状图的颜色
                                            //color: "#000",
                                        }
                                    }
                                },
                                label: {
                                    // formatter: '{b|{b}}\n \n {per|{d}%}  ',
                                    formatter: '{b|{b}}',
                                    borderWidth: 20,
                                    borderRadius: 4,
                                    padding: [20, 40],
                                    normal: {
                                        //点击提示文字换行
                                        formatter(params) {
                                            let text = params.name
                                            if (text.length <= 6) {
                                                return text = text + '\n' + params.percent + '%';
                                            } else if (text.length > 6 && text.length <= 12) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 12 && text.length <= 18) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 24 && text.length <= 30) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 30) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24, 30)}\n${text.slice(30)}`
                                                    + params.percent + '%'
                                            }
                                        },
                                        textStyle: {
                                            fontSize: 8
                                        },
                                    },
                                    rich: {//点击提示文字样式
                                        a: {
                                            color: '#6E7079',
                                            lineHeight: 22,
                                            align: 'center'
                                        },
                                        b: {
                                            color: '#4C5058',
                                            fontSize: 12,
                                            fontWeight: 'bold',
                                            lineHeight: 18,
                                            align: "bottom",
                                            font: "Xingkai SC",
                                        },
                                        c: {
                                            fontSize: 12,
                                            lineHeight: 30,
                                            color: '#63BF6A',
                                            align: "center"
                                        },
                                        d: {
                                            fontSize: 10,
                                            lineHeight: 12,
                                            color: '#4C5058',
                                            align: "top"
                                        }
                                    }
                                },
                                //data: pieModel.pieArr,//饼状图数据
                                data: data.videoData.map((item, index) => {
                                    var fontColor = colorArr[(index % colorArr.length)]
                                    item.label = {
                                        color: fontColor//饼状图文字颜色
                                    }
                                    return item;
                                }),
                                itemStyle: {
                                    //扇形颜色
                                    color: function (params) {
                                        var index = params.dataIndex;
                                        return colorArr[(index % colorArr.length)];
                                    },
                                }
                            }
                        ]
                    };
                    const pieEchart = echarts.init(this.$refs.pieEchartRef)
                    pieEchart.setOption(picOption)

效果图。

1.4. 折线图、柱状图、饼图图实现

效果图

完整代码

javascript 复制代码
<template>
    <el-row class="home-layout" :gutter="20">
        <!--用户布局-->
        <el-col :span="9" class="left-section">
            <el-card shadow="hover">
                <div class="user-layout">
                    <img class="user-header" :src="userImg"/>
                    <div class="user-info-layout">
                        <p class="user-name">Admin</p>
                        <p class="user-nickname">超级管理员</p>
                    </div>
                </div>
                <div class="login-layout">
                    <p class="login-time">上次登录时间:<span>2024-12-12</span></p>
                    <p class="login-loc">上次登录地点:<span>济南</span></p>
                </div>
            </el-card>
            <!--列表展示-->
            <el-card class="list-section">
                <el-table :data="tableData">
                    <el-table-column
                            v-for="(val,key) in tableLabel"
                            :key="key"
                            :prop="key"
                            :label="val">
                    </el-table-column>
                </el-table>
            </el-card>
        </el-col>
        <!--右侧布局-->
        <el-col class="right-section" :span="15">
            <!--订单统计-->
            <el-col :span="8" v-for="(item) in countData"
                    :key="item.name" :offset="0">
                <el-card class="order-section"
                         :body-style="{display:'flex', padding:0}">
                    <div class="order-layout">
                        <i class="order-icon" :class="'el-icon-'+item.icon"
                           :style="{background:item.color}"></i>
                        <div class="order-detail">
                            <p class="order-num">¥{{item.value}}</p>
                            <p class="order-title">{{item.name}}</p>
                        </div>
                    </div>
                </el-card>
            </el-col>
            <!--折线图-->
            <el-card class="echars-line-layout">
                <div class="echars-line-graph" ref="lineEchartRef"></div>
            </el-card>
            <div class="graph-layout">
                <!--条形图-->
                <el-card class="graph-item1">
                    <div style="height:210px" ref='barEchartRef'></div>
                </el-card>
                <!--饼图-->
                <el-card class="graph-item2">
                    <div style="height:180px" ref='pieEchartRef'></div>
                </el-card>
            </div>
        </el-col>
    </el-row>
</template>

<script>
    //import {getMenu} from '../../api/data.js'
    import {getData} from '@/api/data'
    //引入echarts
    import * as echarts from 'echarts'

    export default {
        name: "home",
        data() {
            return {
                userImg: require("../../assets/images/user.png"),
                tableData: [
                    {
                        name: "华为",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "荣耀",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "oppo",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "vivo",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "苹果",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "小米",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "三星",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "魅族",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    }
                ],
                tableLabel: {
                    name: '课程',
                    todayBuy: '今日购买',
                    monthBuy: '本月购买',
                    totalBuy: '总购买',
                },
                countData: [
                    {
                        name: "今日支付订单",
                        value: 1234,
                        icon: "success",
                        color: "#2ec7c9",
                    },
                    {
                        name: "今日收藏订单",
                        value: 210,
                        icon: "star-on",
                        color: "#ffb980",
                    },
                    {
                        name: "今日未支付订单",
                        value: 1234,
                        icon: "s-goods",
                        color: "#5ab1ef",
                    },
                    {
                        name: "本月支付订单",
                        value: 1234,
                        icon: "s-home",
                        color: "#fbcc00",
                    },
                    {
                        name: "本月收藏订单",
                        value: 210,
                        icon: "s-cooperation",
                        color: "#ff4444",
                    },
                    {
                        name: "本月未支付订单",
                        value: 1234,
                        icon: "s-shop",
                        color: "#33cc87",
                    },
                ]
            }
        },
        mounted() {
            //===============
            // //接口请求一般在mounted下
            // const axios = require('axios');
            // // 上述请求也可以按以下方式完成(可选)
            // axios.get('/user', {
            //     params: {
            //         ID: 12345
            //     }
            // }).then(function (response) {
            //         console.log(response);
            //     })
            //     .catch(function (error) {
            //         console.log(error);
            //     })
            //     .finally(function () {
            //         // 总是会执行
            //     });
            //===============
            // getMenu().then(res => {
            //     console.log("post==",res)
            // })
            //===============
            // getData().then(res => {
            //     console.log("getData",res)
            // })
            //===============将数据进行解构
            // getData().then(res => {
            //     const { code,data } = res.data
            //     if (code === 20000){
            //         this.tableData = data.tableData
            //     }
            //     console.log(res)
            // })
            getData().then(res => {
                const {code, data} = res.data
                if (code === 20000) {
                    this.tableData = data.tableData
                    const order = data.orderData
                    const xData = order.date
                    const keyArray = Object.keys(order.data[0])
                    const series = []
                    keyArray.forEach(key => {
                        series.push({
                            name: key,
                            data: order.data.map(item => item[key]),
                            type: 'line'
                        })
                    })
                    const option = {
                        xAxis: {
                            data: xData
                        },
                        yAxis: {},
                        legend: {
                            data: keyArray
                        },
                        series: series
                    }
                    const lineEchart = echarts.init(this.$refs.lineEchartRef)
                    lineEchart.setOption(option)

                    //柱状图
                    const userOption = {
                        legend: {
                            // 图例文字颜色
                            textStyle: {
                                color: "#333",
                            },
                        },
                        grid: {
                            left: "20%",
                        },
                        // 提示框
                        tooltip: {
                            trigger: "axis",
                        },
                        xAxis: {
                            type: "category", // 类目轴
                            data: data.userData.map(item => item.date),
                            axisLine: {
                                lineStyle: {
                                    color: "#17b3a3",
                                },
                            },
                            axisLabel: {
                                interval: 0,
                                color: "#333",
                            },
                        },
                        yAxis: [
                            {
                                type: "value",
                                axisLine: {
                                    lineStyle: {
                                        color: "#17b3a3",
                                    },
                                },
                            },
                        ],
                        color: ["#2ec7c9", "#b6a2de"],
                        series: [
                            {
                                name: '新增用户',
                                data: data.userData.map(item => item.new),
                                type: 'bar'
                            },
                            {
                                name: '活跃用户',
                                data: data.userData.map(item => item.active),
                                type: 'bar'
                            }
                        ],
                    }
                    const barEchart = echarts.init(this.$refs.barEchartRef)
                    barEchart.setOption(userOption)

                    let colorArr = [
                        "#0f78f4",
                        "#dd536b",
                        "#9462e5",
                        "#a6a6a6",
                        "#e1bb22",
                        "#39c362",
                        "#3ed1cf",
                    ]
                    const picOption = {
                        title: {//标题
                            subtext: "",
                            text: "饼图数据统计",
                            top: 'top',
                            left: 'center',
                            textStyle: {
                                fontSize: 11,
                            }
                        },
                        legend: {
                            itemHeight: 8,
                            itemWidth: 8,
                            // type: 'scroll',
                            orient: 'horizontal', // vertical
                            x: 'center',//可设定图例在左、右、居中
                            y: 'bottom',//可设定图例在上、下、居中
                            // padding:[0,50,0,0],//可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                            data: data.videoData,
                            //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                            // diamond:菱形 pin:水滴  arrow:箭头
                            icon: 'rect',
                        },
                        tooltip: {//弹出框
                            //trigger:触发类型,'item'数据项图形触发,主要在散点图,
                            // 饼图等无类目轴的图表中使用。'axis'坐标轴触发,主要在柱状图,
                            // 折线图等会使用类目轴的图表中使用。
                            trigger: 'item',
                            //triggerOn:提示框触发的条件,'mousemove'鼠标移动时触发。
                            // 'click'鼠标点击时触发。'mousemove|click'同时鼠标移动和点击时触发。
                            // 'none'不在 'mousemove' 或 'click' 时触发
                            //triggerOn:"mousemove",
                            //是否显示提示框浮层
                            //showContent:true,
                            //是否永远显示提示框内容
                            //alwaysShowContent:false,
                            //浮层显示的延迟,单位为 ms
                            //showDelay:0,
                            //浮层隐藏的延迟,单位为 ms
                            //hideDelay:100,
                            //鼠标是否可进入提示框浮层中
                            //enterable:false,
                            //是否将 tooltip 框限制在图表的区域内
                            confine: true,
                            //提示框浮层的移动动画过渡时间,单位是 s,设置为 0 的时候会紧跟着鼠标移动
                            //transitionDuration:0.4,
                            //提示框浮层的位置,默认不设置时位置会跟随鼠标的位置,[10, 10],回掉函数,
                            // inside鼠标所在图形的内部中心位置,top、left、bottom、right
                            // 鼠标所在图形上侧,左侧,下侧,右侧,
                            //position:['50%', '50%'],
                            //提示框浮层内容格式器,支持字符串模板和回调函数两种形式,
                            // 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等
                            //formatter:"{b0}: {c0}<br />{b1}: {c1}",
                            // formatter: '{a} <br/>{b}: {c} ({d}%)'
                            formatter: '{b} <br/> {c}件({d}%)',
                            //标题背景色,
                            //backgroundColor:"white",
                            //边框颜色
                            //borderColor:"#ccc",
                            //边框线宽
                            //borderWidth:0,
                            //图例内边距,单位px  5  [5, 10]  [5,10,5,10]
                            padding: 4,
                            //textStyle:文本样式
                            textStyle: {
                                fontSize: 10,
                            }
                        },
                        series: [
                            {
                                name: '统计分析',
                                type: 'pie',
                                clickable: true,//是否开启点击
                                minAngle: 2,//最小的扇区角度(0 ~ 360),防止某个值过小导致扇区太小影响交互
                                avoidLabelOverlap: true,//是否启用防止标签重叠策略
                                hoverAnimation: true,//是否开启 hover 在扇区上的放大动画效果。
                                silent: false,//图形是否不响应和触发鼠标事件
                                radius: ['30%', '50%'],//扇形环宽度
                                center: ['50%', '50%'],
                                labelLine: {
                                    normal: {
                                        length: 10, //第一条线
                                        length2: 8, //第二条线
                                        lineStyle: {
                                            width: 1, // 线条的宽度
                                            //线的颜色设置,如没有设置颜色则线条的颜色跟随饼状图的颜色
                                            //color: "#000",
                                        }
                                    }
                                },
                                label: {
                                    // formatter: '{b|{b}}\n \n {per|{d}%}  ',
                                    formatter: '{b|{b}}',
                                    borderWidth: 20,
                                    borderRadius: 4,
                                    padding: [20, 40],
                                    normal: {
                                        //点击提示文字换行
                                        formatter(params) {
                                            let text = params.name
                                            if (text.length <= 6) {
                                                return text = text + '\n' + params.percent + '%';
                                            } else if (text.length > 6 && text.length <= 12) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 12 && text.length <= 18) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 24 && text.length <= 30) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24)}`
                                                    + params.percent + '%'
                                            } else if (text.length > 30) {
                                                return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24, 30)}\n${text.slice(30)}`
                                                    + params.percent + '%'
                                            }
                                        },
                                        textStyle: {
                                            fontSize: 8
                                        },
                                    },
                                    rich: {//点击提示文字样式
                                        a: {
                                            color: '#6E7079',
                                            lineHeight: 22,
                                            align: 'center'
                                        },
                                        b: {
                                            color: '#4C5058',
                                            fontSize: 12,
                                            fontWeight: 'bold',
                                            lineHeight: 18,
                                            align: "bottom",
                                            font: "Xingkai SC",
                                        },
                                        c: {
                                            fontSize: 12,
                                            lineHeight: 30,
                                            color: '#63BF6A',
                                            align: "center"
                                        },
                                        d: {
                                            fontSize: 10,
                                            lineHeight: 12,
                                            color: '#4C5058',
                                            align: "top"
                                        }
                                    }
                                },
                                //data: pieModel.pieArr,//饼状图数据
                                data: data.videoData.map((item, index) => {
                                    var fontColor = colorArr[(index % colorArr.length)]
                                    item.label = {
                                        color: fontColor//饼状图文字颜色
                                    }
                                    return item;
                                }),
                                itemStyle: {
                                    //扇形颜色
                                    color: function (params) {
                                        var index = params.dataIndex;
                                        return colorArr[(index % colorArr.length)];
                                    },
                                }
                            }
                        ]
                    };
                    const pieEchart = echarts.init(this.$refs.pieEchartRef)
                    pieEchart.setOption(picOption)
                }
            })
        }
    }
</script>
<style lang="less">
    .home-layout {
        height: 100%;
        padding: 10px 0;
    }

    /*用户模块*/
    .left-section {
    }

    .user-layout {
        display: flex;
        flex-direction: row;
        align-items: center;
        border-bottom: #999 solid 1px;
        padding: 0 0 10px;
    }

    .user-header {
        width: 80px;
        height: 80px;
        border-radius: 50%;
    }

    .user-info-layout {
        display: flex;
        flex-direction: column;
        margin-left: 20px;
    }

    .user-name {
        font-size: 18px;
        color: black;
        font-weight: 700;
    }

    .user-nickname {
        font-size: 18px;
        color: black;
        margin-top: 5px;
        font-weight: 700;
    }

    .login-layout {
        display: flex;
        flex-direction: column;
        margin-left: 20px;
    }

    .login-time {
        font-size: 17px;
        color: black;
        margin-top: 5px;
    }

    .login-loc {
        font-size: 17px;
        color: black;
        margin-top: 8px;
    }

    /*列表展示*/
    .list-section {
        margin: 15px 0;
        height: 470px;
    }

    /*订单统计*/
    .order-section {
        padding: 0 0;
        margin: 10px 0 10px;
        background-color: white;
    }

    .order-layout {
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .order-icon {
        display: flex;
        width: 65px;
        height: 65px;
        //border-radius: 50%;
        align-items: center;
        justify-content: center;
    }

    .order-detail {
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin-left: 15px;
    }

    .order-num {
        color: #333333;
        font-size: 18px;
    }

    .order-title {
        color: #333;
        font-size: 18px;
        font-weight: 700;
        margin-top: 8px;
    }

    /*右侧布局*/
    .right-section {
    }

    /*图标布局*/
    .echars-line-layout {
        margin: 10px 0;
    }

    .echars-line-graph {
        height: 230px;
    }

    .graph-layout {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        margin: 10px 0;
    }

    .graph-item1 {
        flex: 1;
        height: 215px;
        margin-right: 5px;

    }

    .graph-item2 {
        flex: 1;
        height: 215px;
        margin-left: 5px;

    }
</style>

Echars折线图、柱状图、饼图基本使用示例下载

1.5. Echars图表封装

(1)在src/components下新建MyEcharts.vue文件

javascript 复制代码
//src/components/MyEcharts.vue
<template>
	<div ref="echartRef"></div>
</template>

<script>
	//引入echarts
	import * as echarts from 'echarts'

	export default {
		props: {
			//判断图表类型(true:柱状图、折线图   false:饼状图)
			isAxisChart: {
				type: Boolean,
				default: true
			},
			//引入option
			chartData: {
				type: Object,
				default () {
					return {
						xData: [],
						series: []
					}
				},
			},
		},
		//监听数据
		watch: {
			chartData: {
				handler: function() {
					this.initEchars()
				},
				deep: true //首次触发
			}
		},
		methods: {
			initEchars() {
				this.initEcharsData()
				if (this.echart) {
					this.echart.setOption(this.options)
				} else {
					this.echart = echarts.init(this.$refs.echartRef)
					this.echart.setOption(this.options)
				}

			},
			initEcharsData() {
				if (this.isAxisChart) {
					this.axisOption.xAxis.data = this.chartData.xData
					this.axisOption.series = this.chartData.series
				} else {
					this.normalOption.series = this.chartData.series
				}
			}
		},
		data() {
			return {
				axisOption: {
					legend: {
						// 图例文字颜色
						textStyle: {
							color: "#333",
						},
					},
					grid: {
						left: "20%",
					},
					// 提示框
					tooltip: {
						trigger: "axis",
					},
					xAxis: {
						type: "category", // 类目轴
						data: [],
						axisLine: {
							lineStyle: {
								color: "#17b3a3",
							},
						},
						axisLabel: {
							interval: 0,
							color: "#333",
						},
					},
					yAxis: [{
						type: "value",
						axisLine: {
							lineStyle: {
								color: "#17b3a3",
							},
						},
					}, ],
					color: ["#0f78f4", "#dd536b", "#9462e5",
						"#a6a6a6", "#e1bb22", "#39c362", "#3ed1cf",
					],
					series: [],
				},
				normalOption: {
					tooltip: {
						trigger: "item",
					},
					color: ["#0f78f4", "#dd536b", "#9462e5",
						"#a6a6a6", "#e1bb22", "#39c362", "#3ed1cf",
					],
					series: [],
				},
				echart: null
			}
		},
		//计算属性
		computed: {
			options() {
				return this.isAxisChart ? this.axisOption : this.normalOption
			}
		}
	}
</script>
<style>
</style>

(1)在src/views/home/index.vue

javascript 复制代码
//src/views/home/index.vue
<template>
    <el-row class="home-layout" :gutter="20">
        <!--用户布局-->
        <el-col :span="9" class="left-section">
            <el-card shadow="hover">
                <div class="user-layout">
                    <img class="user-header" :src="userImg"/>
                    <div class="user-info-layout">
                        <p class="user-name">Admin</p>
                        <p class="user-nickname">超级管理员</p>
                    </div>
                </div>
                <div class="login-layout">
                    <p class="login-time">上次登录时间:<span>2024-12-12</span></p>
                    <p class="login-loc">上次登录地点:<span>济南</span></p>
                </div>
            </el-card>
            <!--列表展示-->
            <el-card class="list-section">
                <el-table :data="tableData">
                    <el-table-column v-for="(val,key) in tableLabel" :key="key" :prop="key" :label="val">
                    </el-table-column>
                </el-table>
            </el-card>
        </el-col>
        <!--右侧布局-->
        <el-col class="right-section" :span="15">
            <!--订单统计-->
            <el-col :span="8" v-for="(item) in countData" :key="item.name" :offset="0">
                <el-card class="order-section" :body-style="{display:'flex', padding:0}">
                    <div class="order-layout">
                        <i class="order-icon" :class="'el-icon-'+item.icon" :style="{background:item.color}"></i>
                        <div class="order-detail">
                            <p class="order-num">¥{{item.value}}</p>
                            <p class="order-title">{{item.name}}</p>
                        </div>
                    </div>
                </el-card>
            </el-col>
            <!--折线图-->
            <el-card class="echars-line-layout">
                <!--普通-->
                <!-- <div class="echars-line-graph" ref="lineEchartRef"></div> -->
                <!--封装-->
                <echart class="echars-line-graph" :chartData="echartData.line"></echart>
            </el-card>
            <div class="graph-layout">
                <!--柱状图-->
                <el-card class="graph-bar-layout">
                    <!--普通-->
                    <!-- <div class="graph-bar-item" ref='barEchartRef'></div> -->
                    <!--封装-->
                    <echart class="graph-bar-item" :chartData="echartData.bar"></echart>
                </el-card>
                <!--饼图-->
                <el-card class="graph-pie-layout">
                    <!--普通-->
                    <!--                     <div class="graph-pie-item" ref='barEchartRef'></div>-->
                    <!--封装-->
                    <echart class="graph-pie-item"
                            :chartData="echartData.pie" :isAxisChart="false"></echart>
                </el-card>
            </div>
        </el-col>
    </el-row>
</template>

<script>
    //import {getMenu} from '../../api/data.js'
    import {
        getData
    } from '@/api/data'
    //引入echarts
    import * as echarts from 'echarts'
    import Echart from '../../components/MyEcharts.vue'

    export default {
        name: "home",
        components: {
            //加入组件
            Echart
        },
        data() {
            return {
                userImg: require("../../assets/images/user.png"),
                //图表
                echartData: {
                    line: {
                        xData: [],
                        series: []
                    },
                    bar: {
                        xData: [],
                        series: []
                    },
                    pie: {
                        series: []
                    }
                },
                tableData: [{
                    name: "华为",
                    todayBuy: 100,
                    monthBuy: 300,
                    totalBuy: 800,
                },
                    {
                        name: "荣耀",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "oppo",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "vivo",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "苹果",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "小米",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "三星",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    },
                    {
                        name: "魅族",
                        todayBuy: 100,
                        monthBuy: 300,
                        totalBuy: 800,
                    }
                ],
                tableLabel: {
                    name: '课程',
                    todayBuy: '今日购买',
                    monthBuy: '本月购买',
                    totalBuy: '总购买',
                },
                countData: [{
                    name: "今日支付订单",
                    value: 1234,
                    icon: "success",
                    color: "#2ec7c9",
                },
                    {
                        name: "今日收藏订单",
                        value: 210,
                        icon: "star-on",
                        color: "#ffb980",
                    },
                    {
                        name: "今日未支付订单",
                        value: 1234,
                        icon: "s-goods",
                        color: "#5ab1ef",
                    },
                    {
                        name: "本月支付订单",
                        value: 1234,
                        icon: "s-home",
                        color: "#fbcc00",
                    },
                    {
                        name: "本月收藏订单",
                        value: 210,
                        icon: "s-cooperation",
                        color: "#ff4444",
                    },
                    {
                        name: "本月未支付订单",
                        value: 1234,
                        icon: "s-shop",
                        color: "#33cc87",
                    },
                ]
            }
        },
        mounted() {
            //===============
            // //接口请求一般在mounted下
            // const axios = require('axios');
            // // 上述请求也可以按以下方式完成(可选)
            // axios.get('/user', {
            //     params: {
            //         ID: 12345
            //     }
            // }).then(function (response) {
            //         console.log(response);
            //     })
            //     .catch(function (error) {
            //         console.log(error);
            //     })
            //     .finally(function () {
            //         // 总是会执行
            //     });
            //===============
            // getMenu().then(res => {
            //     console.log("post==",res)
            // })
            //===============
            // getData().then(res => {
            //     console.log("getData",res)
            // })
            //===============将数据进行解构
            // getData().then(res => {
            //     const { code,data } = res.data
            //     if (code === 20000){
            //         this.tableData = data.tableData
            //     }
            //     console.log(res)
            // })
            getData().then(res => {
                const {
                    code,
                    data
                } = res.data
                if (code === 20000) {
                    this.tableData = data.tableData
                    const order = data.orderData
                    const xData = order.date
                    const keyArray = Object.keys(order.data[0])
                    const series = []
                    keyArray.forEach(key => {
                        series.push({
                            name: key,
                            data: order.data.map(item => item[key]),
                            type: 'line'
                        })
                    })
                    //折线图
                    //=====普通=====
                    // const option = {
                    // 	xAxis: {
                    // 		data: xData
                    // 	},
                    // 	yAxis: {},
                    // 	legend: {
                    // 		data: keyArray
                    // 	},
                    // 	series: series
                    // }
                    // const lineEchart = echarts.init(this.$refs.lineEchartRef)
                    // lineEchart.setOption(option)
                    //=====封装=====
                    this.echartData.line.xData = xData
                    this.echartData.line.series = series

                    //柱状图
                    //=====普通=====
                    // const userOption = {
                    //     legend: {
                    //         // 图例文字颜色
                    //         textStyle: {
                    //             color: "#333",
                    //         },
                    //     },
                    //     grid: {
                    //         left: "20%",
                    //     },
                    //     // 提示框
                    //     tooltip: {
                    //         trigger: "axis",
                    //     },
                    //     xAxis: {
                    //         type: "category", // 类目轴
                    //         data: data.userData.map(item => item.date),
                    //         axisLine: {
                    //             lineStyle: {
                    //                 color: "#17b3a3",
                    //             },
                    //         },
                    //         axisLabel: {
                    //             interval: 0,
                    //             color: "#333",
                    //         },
                    //     },
                    //     yAxis: [{
                    //         type: "value",
                    //         axisLine: {
                    //             lineStyle: {
                    //                 color: "#17b3a3",
                    //             },
                    //         },
                    //     },],
                    //     color: ["#2ec7c9", "#b6a2de"],
                    //     series: [{
                    //         name: '新增用户',
                    //         data: data.userData.map(item => item.new),
                    //         type: 'bar'
                    //     },
                    //         {
                    //             name: '活跃用户',
                    //             data: data.userData.map(item => item.active),
                    //             type: 'bar'
                    //         }
                    //     ],
                    // }
                    // const barEchart = echarts.init(this.$refs.barEchartRef)
                    // barEchart.setOption(userOption)
                    //饼图图
                    //=====普通=====
                    this.echartData.bar.xData = data.userData.map(item => item.date)
                    this.echartData.bar.series = [{
                        name: '新增用户',
                        data: data.userData.map(item => item.new),
                        type: 'bar'
                    },
                        {
                            name: '活跃用户',
                            data: data.userData.map(item => item.active),
                            type: 'bar'
                        }
                    ]
                    //=====封装=====
                    // let colorArr = [
                    //     "#0f78f4",
                    //     "#dd536b",
                    //     "#9462e5",
                    //     "#a6a6a6",
                    //     "#e1bb22",
                    //     "#39c362",
                    //     "#3ed1cf",
                    // ]
                    // const pieOption = {
                    //     title: { //标题
                    //         subtext: "",
                    //         text: "饼图数据统计",
                    //         top: 'top',
                    //         left: 'center',
                    //         textStyle: {
                    //             fontSize: 11,
                    //         }
                    //     },
                    //     legend: {
                    //         itemHeight: 8,
                    //         itemWidth: 8,
                    //         // type: 'scroll',
                    //         orient: 'horizontal', // vertical
                    //         x: 'center', //可设定图例在左、右、居中
                    //         y: 'bottom', //可设定图例在上、下、居中
                    //         // padding:[0,50,0,0],//可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                    //         data: data.videoData,
                    //         //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                    //         // diamond:菱形 pin:水滴  arrow:箭头
                    //         icon: 'rect',
                    //     },
                    //     tooltip: { //弹出框
                    //         //trigger:触发类型,'item'数据项图形触发,主要在散点图,
                    //         // 饼图等无类目轴的图表中使用。'axis'坐标轴触发,主要在柱状图,
                    //         // 折线图等会使用类目轴的图表中使用。
                    //         trigger: 'item',
                    //         //triggerOn:提示框触发的条件,'mousemove'鼠标移动时触发。
                    //         // 'click'鼠标点击时触发。'mousemove|click'同时鼠标移动和点击时触发。
                    //         // 'none'不在 'mousemove' 或 'click' 时触发
                    //         //triggerOn:"mousemove",
                    //         //是否显示提示框浮层
                    //         //showContent:true,
                    //         //是否永远显示提示框内容
                    //         //alwaysShowContent:false,
                    //         //浮层显示的延迟,单位为 ms
                    //         //showDelay:0,
                    //         //浮层隐藏的延迟,单位为 ms
                    //         //hideDelay:100,
                    //         //鼠标是否可进入提示框浮层中
                    //         //enterable:false,
                    //         //是否将 tooltip 框限制在图表的区域内
                    //         confine: true,
                    //         //提示框浮层的移动动画过渡时间,单位是 s,设置为 0 的时候会紧跟着鼠标移动
                    //         //transitionDuration:0.4,
                    //         //提示框浮层的位置,默认不设置时位置会跟随鼠标的位置,[10, 10],回掉函数,
                    //         // inside鼠标所在图形的内部中心位置,top、left、bottom、right
                    //         // 鼠标所在图形上侧,左侧,下侧,右侧,
                    //         //position:['50%', '50%'],
                    //         //提示框浮层内容格式器,支持字符串模板和回调函数两种形式,
                    //         // 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等
                    //         //formatter:"{b0}: {c0}<br />{b1}: {c1}",
                    //         // formatter: '{a} <br/>{b}: {c} ({d}%)'
                    //         formatter: '{b} <br/> {c}件({d}%)',
                    //         //标题背景色,
                    //         //backgroundColor:"white",
                    //         //边框颜色
                    //         //borderColor:"#ccc",
                    //         //边框线宽
                    //         //borderWidth:0,
                    //         //图例内边距,单位px  5  [5, 10]  [5,10,5,10]
                    //         padding: 4,
                    //         //textStyle:文本样式
                    //         textStyle: {
                    //             fontSize: 10,
                    //         }
                    //     },
                    //     series: [{
                    //         name: '统计分析',
                    //         type: 'pie',
                    //         clickable: true, //是否开启点击
                    //         minAngle: 2, //最小的扇区角度(0 ~ 360),防止某个值过小导致扇区太小影响交互
                    //         avoidLabelOverlap: true, //是否启用防止标签重叠策略
                    //         hoverAnimation: true, //是否开启 hover 在扇区上的放大动画效果。
                    //         silent: false, //图形是否不响应和触发鼠标事件
                    //         radius: ['30%', '50%'], //扇形环宽度
                    //         center: ['50%', '50%'],
                    //         labelLine: {
                    //             normal: {
                    //                 length: 10, //第一条线
                    //                 length2: 8, //第二条线
                    //                 lineStyle: {
                    //                     width: 1, // 线条的宽度
                    //                     //线的颜色设置,如没有设置颜色则线条的颜色跟随饼状图的颜色
                    //                     //color: "#000",
                    //                 }
                    //             }
                    //         },
                    //         label: {
                    //             // formatter: '{b|{b}}\n \n {per|{d}%}  ',
                    //             formatter: '{b|{b}}',
                    //             borderWidth: 20,
                    //             borderRadius: 4,
                    //             padding: [20, 40],
                    //             normal: {
                    //                 //点击提示文字换行
                    //                 formatter(params) {
                    //                     let text = params.name
                    //                     if (text.length <= 6) {
                    //                         return text = text + '\n' + params.percent + '%';
                    //                     } else if (text.length > 6 && text.length <= 12) {
                    //                         return text = `${text.slice(0, 6)}\n${text.slice(6)}` +
                    //                             params.percent + '%'
                    //                     } else if (text.length > 12 && text.length <= 18) {
                    //                         return text =
                    //                             `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12)}` +
                    //                             params.percent + '%'
                    //                     } else if (text.length > 24 && text.length <= 30) {
                    //                         return text =
                    //                             `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24)}` +
                    //                             params.percent + '%'
                    //                     } else if (text.length > 30) {
                    //                         return text =
                    //                             `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24, 30)}\n${text.slice(30)}` +
                    //                             params.percent + '%'
                    //                     }
                    //                 },
                    //                 textStyle: {
                    //                     fontSize: 8
                    //                 },
                    //             },
                    //             rich: { //点击提示文字样式
                    //                 a: {
                    //                     color: '#6E7079',
                    //                     lineHeight: 22,
                    //                     align: 'center'
                    //                 },
                    //                 b: {
                    //                     color: '#4C5058',
                    //                     fontSize: 12,
                    //                     fontWeight: 'bold',
                    //                     lineHeight: 18,
                    //                     align: "bottom",
                    //                     font: "Xingkai SC",
                    //                 },
                    //                 c: {
                    //                     fontSize: 12,
                    //                     lineHeight: 30,
                    //                     color: '#63BF6A',
                    //                     align: "center"
                    //                 },
                    //                 d: {
                    //                     fontSize: 10,
                    //                     lineHeight: 12,
                    //                     color: '#4C5058',
                    //                     align: "top"
                    //                 }
                    //             }
                    //         },
                    //         //data: pieModel.pieArr,//饼状图数据
                    //         data: data.videoData.map((item, index) => {
                    //             var fontColor = colorArr[(index % colorArr.length)]
                    //             item.label = {
                    //                 color: fontColor //饼状图文字颜色
                    //             }
                    //             return item;
                    //         }),
                    //         itemStyle: {
                    //             //扇形颜色
                    //             color: function (params) {
                    //                 var index = params.dataIndex;
                    //                 return colorArr[(index % colorArr.length)];
                    //             },
                    //         }
                    //     }]
                    // };
                    // const pieOption = {
                    //     tooltip: {
                    //         trigger: "item",
                    //     },
                    //     color: [
                    //         "#0f78f4",
                    //         "#dd536b",
                    //         "#9462e5",
                    //         "#a6a6a6",
                    //         "#e1bb22",
                    //         "#39c362",
                    //         "#3ed1cf",
                    //     ],
                    //     series: [
                    //         {
                    //             data:data.videoData,
                    //             type:'pie'
                    //         }
                    //     ],
                    // }
                    // const pieEchart = echarts.init(this.$refs.pieEchartRef)
                    // pieEchart.setOption(pieOption)
                    //=====封装=====
                    this.echartData.pie.series= [
                            {
                                data:data.videoData,
                                type:'pie'
                            }
                        ]
                }
            })
        }
    }
</script>
<style lang="less">
    .home-layout {
        height: 100%;
        padding: 10px 0;
    }

    /*用户模块*/
    .left-section {
    }

    .user-layout {
        display: flex;
        flex-direction: row;
        align-items: center;
        border-bottom: #999 solid 1px;
        padding: 0 0 10px;
    }

    .user-header {
        width: 80px;
        height: 80px;
        border-radius: 50%;
    }

    .user-info-layout {
        display: flex;
        flex-direction: column;
        margin-left: 20px;
    }

    .user-name {
        font-size: 18px;
        color: black;
        font-weight: 700;
    }

    .user-nickname {
        font-size: 18px;
        color: black;
        margin-top: 5px;
        font-weight: 700;
    }

    .login-layout {
        display: flex;
        flex-direction: column;
        margin-left: 20px;
    }

    .login-time {
        font-size: 17px;
        color: black;
        margin-top: 5px;
    }

    .login-loc {
        font-size: 17px;
        color: black;
        margin-top: 8px;
    }

    /*列表展示*/
    .list-section {
        margin: 15px 0;
        height: 470px;
    }

    /*订单统计*/
    .order-section {
        padding: 0 0;
        margin: 10px 0 10px;
        background-color: white;
    }

    .order-layout {
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .order-icon {
        display: flex;
        width: 65px;
        height: 65px;
        //border-radius: 50%;
        align-items: center;
        justify-content: center;
    }

    .order-detail {
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin-left: 15px;
    }

    .order-num {
        color: #333333;
        font-size: 18px;
    }

    .order-title {
        color: #333;
        font-size: 18px;
        font-weight: 700;
        margin-top: 8px;
    }

    /*右侧布局*/
    .right-section {
    }

    /*图标布局*/
    .echars-line-layout {
        margin: 10px 0;
    }

    .echars-line-graph {
        height: 230px;
    }

    .graph-layout {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        margin: 10px 0;
    }

    .graph-bar-layout {
        flex: 1;
        height: 215px;
        margin-right: 5px;
    }

    .graph-bar-item {
        height: 210px;
    }

    .graph-pie-layout {
        flex: 1;
        height: 215px;
        margin-left: 5px;
    }

    .graph-pie-item {
        height: 180px;
    }
</style>

效果图

VueWeb Echars图表折线图、柱状图、饼图封装示例下载

相关推荐
辰星s2 分钟前
HTML/CSS总结
前端·css·html
布兰妮甜10 分钟前
使用Svelte构建轻量级应用详解
前端·javascript·框架·svelte
顽疲41 分钟前
从零用java实现 小红书 springboot vue uniapp (3)详情页优化
java·vue.js·spring boot·uniapp
快乐点吧1 小时前
【前端面试】前端工程化
前端·面试·职场和发展
街尾杂货店&1 小时前
webpack说明
前端·webpack·node.js
我是唐赢1 小时前
微信小程序混入Behavior,实现Vue mixins同样功能
javascript·vue.js·微信小程序
知忆_IS1 小时前
【GIS教程】使用GDAL-Python将tif转为COG并在ArcGIS Js前端加载-附完整代码
前端·javascript·arcgis
Domain-zhuo1 小时前
如何理解React State不可变性的原则
前端·javascript·react native·react.js·前端框架·ecmascript
开心工作室_kaic1 小时前
springboot422甘肃旅游服务平台代码-(论文+源码)_kaic
前端·spring boot·旅游