vue-element-admin 综合开发五:引入 echarts,封装echarts 组件

文章目录

  • 导言
  • 一、初尝试echarts
    • 1. 引入方式
    • 2. 项目新建 echarts.html
    • 3. 页面展示
  • 二、 项目引入echarts
    • 1. 安装
    • 2. 引入
  • 三、本项目开发:折线图、柱状图、饼图
    • 1. 数据来源
    • 2. 折线图
      • a、dom位置
      • b、method 定义 echarts 折线图
      • c、方法挂载到 mounted 钩子函数
    • 3. 柱状图
      • a、dom位置
      • b、method 定义 echarts 柱状图
      • c、挂载到mounted
    • 4. 饼图
      • a、dom位置
      • b、method 定义的 echarts 饼状图
      • c、挂载到mounted 钩子函数
    • 5. ==引出的问题==
  • 四、封装echarts组件
    • 1. 新建组件: components/Echarts.vue
    • 2. 修改 home/index.vue
      • a、引入 Echarts组件
      • b、html 改变
      • c、数据改变
    • 3. 柱状图、饼状图同理
  • 五、最终界面

导言

一、初尝试echarts

  1. ecahrts 官网:https://echarts.apache.org/zh/index.html
  2. 学习使用跟着官网走即可
  3. API位置:

1. 引入方式

  1. 根据官网去下载
  2. cdn方式:
    <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
    

2. 项目新建 echarts.html

将官网的事例拿过来,换上 上面的cdn方式

DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>EChartstitle>
    
    <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js">script>
  head>
  <body>
    
    <div id="main" style="width: 600px;height:400px;">div>
    <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('main'));

      // 指定图表的配置项和数据
      var option = {
        title: {
          text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      };

      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    script>
  body>
html>

3. 页面展示

二、 项目引入echarts

1. 安装

npm install [email protected] or yarn add [email protected]

2. 引入

哪个页面用,就在哪个页面引入即可(无须在main.js中引入
引入语句

import * as echarts from "echarts";

三、本项目开发:折线图、柱状图、饼图

1. 数据来源

在上一个博文中使用了mock数据模拟后端返回的数据,在 /home/getData 这个请求中返回了所有数据,包括上一个博客已经用到的列表数据,还有本博客的折线图、柱状图、饼状图的数据。

2. 折线图

a、dom位置

dom位置:放折线图的地方

      
      <el-card style="height: 280px">
        <div style="height: 280px" ref="echarts">div>
      el-card>

b、method 定义 echarts 折线图

  1. method 定义的方法
   // 折线图
    zhexiantu(data) {
      // 折线图
      const order = data.orderData;
      const xData = order.date;
      // console.log(JSON.stringify(xData))
      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,
      };
      const e = echarts.init(this.$refs.echarts);
      e.setOption(option);
    },

c、方法挂载到 mounted 钩子函数

  1. 将方法放到 mounted 钩子函数中调用
  mounted() {
    getData().then((res) => {
      const { code, data } = res.data;
      if (code == 20000) {
        // 左下方表格
        this.tableData = data.tableData;
        // 右方 中间 折线图
        this.zhexiantu(data);
      }
      console.log("res:", res);
    });
  },
  1. 注意这里的数据,还是之前封装的mock数据,mock数据。

3. 柱状图

a、dom位置

        <el-card style="height: 260px">
          <div style="height: 240px" ref="userEcharts">div>
        el-card>

b、method 定义 echarts 柱状图

	// 柱状图
    zhuzhuangtu(data) {
      const userOption = {
        legend: {
          // 图例文字颜色
          textStyle: {
            color: "#333",
          },
        },
        grid: {
          left: "20%",
        },
        // 提示框
        tooltip: {
          trigger: "axis",
        },
        xAxis: {
          type: "category", // 类目轴
          data: data.userData.map((item) => item.data),
          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 e = echarts.init(this.$refs.userEcharts);
      e.setOption(userOption);
    },

c、挂载到mounted

  mounted() {
    getData().then((res) => {
      const { code, data } = res.data;
      if (code == 20000) {
        // 左下方表格
        this.tableData = data.tableData;
        // 右方 中间 折线图
        this.zhexiantu(data);
        // 右方 下面 柱状图
        this.zhuzhuangtu(data);
      }
      console.log("res:", res);
    });
  },

4. 饼图

a、dom位置

        <el-card style="height: 260px">
          <div style="height: 240px" ref="videoEcharts">div>
        el-card>

b、method 定义的 echarts 饼状图

    // 饼图
    bingtu(data) {
      const videoOption = {
        tooltip: {
          trigger: "item",
        },
        color: [
          "#0f78f4",
          "#dd536b",
          "#9462e5",
          "#a6a6a6",
          "#e1bb22",
          "#39c362",
          "#3ed1cf",
        ],
        series: [
          {
            data: data.videoData,
            type: 'pie'
          }
        ],
      };
      const e = echarts.init(this.$refs.videoEcharts)
      e.setOption(videoOption)
    },

c、挂载到mounted 钩子函数

  mounted() {
    getData().then((res) => {
      const { code, data } = res.data;
      if (code == 20000) {
        // 左下方表格
        this.tableData = data.tableData;
        // 右方 中间 折线图
        this.zhexiantu(data);
        // 右方 下面 柱状图
        this.zhuzhuangtu(data);
        // 右方 下面 饼图
        this.bingtu(data);
      }
      console.log("res:", res);
    });
  },

5. 引出的问题

一个页面有三个E chart图,然后引用了三次,代码冗余有点多,应该封装出一个Echart 组件。

四、封装echarts组件

1. 新建组件: components/Echarts.vue

  1. 将图表分为 线性图饼图 两类。
  2. 父组件 传到 子组件的 isAxisChart 属性 用于区分 线性图和饼图
  3. watch 监听入口
<template>
  <div ref="echart">div>
template>
<script>
import * as echarts from 'echarts'
export default {
  name: 'Echart',
  props: {
    isAxisChart: {
      type: Boolean, // true 代表 线性图, false 代表 饼状图
      default: true
    },
    chartData: {
      type: Object,
      default(){
        return {
          xData: [],
          series: [],
        }
      }
    }
  },
  // 监听
  watch: {
    // chartData 是props 中父组件传过来的数据
    chartData: {
      // 入口  handler : 固定
      handler: function(){
        console.log('echarts, echart:', this.echart) // 第一次为 undefined 以后都有值
        this.initChart()
        console.log('echarts, this.option:', this.option)
        console.log('echarts, this.option type:', typeof(this.option))
        console.log('echarts, isAxisChart:', this.isAxisChart)
      },
      // 首次对数据监听的话 不应该加的是immediate吗,这里的deep 是应为 chartData 是对象才用的 深入deep吧。
      deep: true
    }
    
  },
  methods: {
    initChart(){
      // 先初始化 图表数据
      this.initChartData()
      // 再 显示图表
      if(this.echart){
        // 已有 echarts 对象
        this.echart.setOption(this.option)
      } else {
        // 没有 echarts 对象
        this.echart = echarts.init(this.$refs.echart)
        this.echart.setOption(this.option)
      }
    },
    initChartData(){
      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 {
      ecahrt: null,
      // 折线图
      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: ["#2ec7c9", "#b6a2de", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3"],
        series: [],
      },
      // 饼状图
      normalOption: {
          tooltip: {
            trigger: "item",
          },
          color: [
            "#0f78f4",
            "#dd536b",
            "#9462e5",
            "#a6a6a6",
            "#e1bb22",
            "#39c362",
            "#3ed1cf",
          ],
          series: [],
        },
    }
  },
  computed: {
    option(){
      // this.isAxisChart 为 true 则获取 饼状图 和折线图 ,否则获取 饼状图 的数据
      return this.isAxisChart ? this.axisOption : this.normalOption
    }
  }
}
script>

2. 修改 home/index.vue

a、引入 Echarts组件

import Echart from '../../components/Echarts.vue'

b、html 改变

c、数据改变

3. 柱状图、饼状图同理

但是饼状图有点问题

五、最终界面

你可能感兴趣的:(vue,echarts,vue.js,javascript)