Vue + ECharts 实现实时数据报表:从入门到掌握」 「超详细!用 Vue 和 ECharts 搭建你的第一个动态报表页面」 「前端新手也能轻松上手的 Vue 报表页面设计:图表+切换标签」

效果图

在这里插入图片描述

博客目录

  1. 介绍与目标
  2. 项目搭建
  3. 页面结构与样式
  4. 数据绑定与动态展示
  5. ECharts 图表配置
  6. 实现标签切换功能
  7. 最终效果与总结

1. 介绍与目标

在本教程中,我们将使用 Vue 2 和 ECharts 搭建一个简单但功能齐全的「租赁报表」页面。本教程适合前端新手学习 Vue 的数据绑定、组件化以及 ECharts 的数据可视化,帮助你快速上手并掌握制作数据报表页面的基本技能。

2. 项目搭建

引入 Vue 和 ECharts

在项目文件中,我们直接通过 CDN 引入 Vue 和 ECharts,无需额外安装复杂的依赖,这样可以更快速地进行页面开发:

<script src="https://cdn.staticfile.net/vue/2.7.0/vue.min.js"></script>
<script src="https://cdn.staticfile.net/echarts/5.0.0/echarts.min.js"></script>

3. 页面结构与样式

在页面结构方面,我们将创建一个包含标题、标签切换、数据摘要以及四个图表的报表页面。所有内容会放在 #app 容器中,利用 Vue 来管理和渲染。

<div id="app">
  <div class="header">报表</div>
  <div class="tabs">
    <div class="tab" :class="{ active: activeTab === 'yesterday' }" @click="setActiveTab('yesterday')">昨日</div>
    <div class="tab" :class="{ active: activeTab === 'today' }" @click="setActiveTab('today')">今日</div>
    <div class="tab" :class="{ active: activeTab === 'thisWeek' }" @click="setActiveTab('thisWeek')">本周</div>
    <div class="tab" :class="{ active: activeTab === 'thisMonth' }" @click="setActiveTab('thisMonth')">本月</div>
  </div>
  <!-- 其余部分继续... -->
</div>
样式设置

页面样式主要使用基础的 CSS 来进行布局和颜色设置,所有样式代码写在 <style> 标签中。

.header {
    
    
  background-color: #2c5cac;
  color: #fff;
  padding: 10px;
  text-align: center;
  font-size: 18px;
  font-weight: bold;
}
.tab.active {
    
    
  color: #2c5cac;
  font-weight: bold;
  border-bottom: 2px solid #2c5cac;
}

4. 数据绑定与动态展示

在 Vue 的 data 选项中,我们定义 activeTabsummaryData,并通过 v-for 绑定到 DOM 中。这样用户可以动态切换标签,同时显示相应的摘要信息。

data: {
    
    
  activeTab: 'yesterday',
  summaryData: [
    {
    
     label: '租赁成交量', value: 49 },
    {
    
     label: '新增租金', value: 3260 },
    {
    
     label: '新增押金', value: 6427 },
    {
    
     label: '用户注册量', value: 86 },
    {
    
     label: '网店注册量', value: 28 },
    {
    
     label: '今日流水', value: 42192 },
  ]
},
methods: {
    
    
  setActiveTab(tab) {
    
    
    this.activeTab = tab;
  }
}

5. ECharts 图表配置

圆环图:电池型号租赁比例

使用 ECharts 的 pie 类型来创建圆环图,用来展示电池型号的租赁比例。图表的配置项在 initDonutChart 方法中设置。

initDonutChart() {
    
    
  const donutChart = echarts.init(this.$refs.donutChart);
  const donutOption = {
    
    
    tooltip: {
    
     trigger: 'item' },
    series: [
      {
    
    
        name: '电池型号租赁比例',
        type: 'pie',
        radius: ['40%', '70%'],
        data: [
          {
    
     value: 42, name: '48V12A' },
          {
    
     value: 25, name: '48V20A' },
          {
    
     value: 25, name: '60V20A' },
          {
    
     value: 8, name: '72V20A' }
        ],
        color: ['#66c2ff', '#ffcc66', '#66ff99', '#ff9966']
      }
    ]
  };
  donutChart.setOption(donutOption);
}
柱状图:电池租赁、商户佣金、城市成交量

三个柱状图分别展示不同的数据内容,方法 initBarChart1initBarChart2initBarChart3 初始化每个图表,并设置相应的数据和颜色。

initBarChart1() {
    
    
  const barChart1 = echarts.init(this.$refs.barChart1);
  const barOption1 = {
    
    
    xAxis: {
    
     type: 'category', data: ['新租', '换租', '退租'] },
    yAxis: {
    
     type: 'value' },
    series: [
      {
    
     data: [568, 303, 124], type: 'bar', itemStyle: {
    
     color: '#66c2ff' } }
    ]
  };
  barChart1.setOption(barOption1);
}

6. 实现标签切换功能

标签切换功能通过 setActiveTab 方法实现。点击标签时会更新 activeTab,同时使选中标签的样式发生变化:

methods: {
    
    
  setActiveTab(tab) {
    
    
    this.activeTab = tab;
  }
}

每个标签的样式在 tab.active 样式类中定义,使选中的标签颜色加深并添加底部边框。

7. 最终效果与总结

通过这篇教程,你应该学会了如何用 Vue 结合 ECharts 实现动态报表页面,包括数据绑定、标签切换、图表配置等。这样的报表页面在管理后台或数据分析平台中非常常见,也是学习 Vue 的重要练习案例之一。

完整代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>报表 - Vue 示例</title>
  <script src="https://cdn.staticfile.net/vue/2.7.0/vue.min.js"></script>
  <script src="https://cdn.staticfile.net/echarts/5.0.0/echarts.min.js"></script>
  <style>
    body {
      
      
      font-family: Arial, sans-serif;
      background-color: #f4f4f4;
      margin: 0;
      padding: 0;
    }
    #app {
      
      
      max-width: 600px;
      margin: 20px auto;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }
    .header {
      
      
      background-color: #2c5cac;
      color: #fff;
      padding: 10px;
      text-align: center;
      font-size: 18px;
      font-weight: bold;
    }
    .tabs {
      
      
      display: flex;
      justify-content: space-around;
      border-bottom: 1px solid #ddd;
    }
    .tab {
      
      
      padding: 10px;
      cursor: pointer;
      flex: 1;
      text-align: center;
      font-size: 14px;
      color: #666;
    }
    .tab.active {
      
      
      color: #2c5cac;
      font-weight: bold;
      border-bottom: 2px solid #2c5cac;
    }
    .summary {
      
      
      display: flex;
      flex-wrap: wrap;
      justify-content: space-around;
      padding: 10px;
      background-color: #f9f9f9;
    }
    .summary-item {
      
      
      width: 45%;
      margin-bottom: 10px;
      text-align: center;
      background-color: #fff;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
    }
    .chart-section {
      
      
      padding: 10px;
    }
    .chart-title {
      
      
      font-weight: bold;
      font-size: 16px;
      margin-bottom: 10px;
    }
    .chart {
      
      
      width: 100%;
      height: 200px;
    }
  </style>
</head>
<body>
<div id="app">
  <!-- Header -->
  <div class="header">报表</div>

  <!-- Tabs -->
  <div class="tabs">
    <div class="tab" :class="{ active: activeTab === 'yesterday' }" @click="setActiveTab('yesterday')">昨日</div>
    <div class="tab" :class="{ active: activeTab === 'today' }" @click="setActiveTab('today')">今日</div>
    <div class="tab" :class="{ active: activeTab === 'thisWeek' }" @click="setActiveTab('thisWeek')">本周</div>
    <div class="tab" :class="{ active: activeTab === 'thisMonth' }" @click="setActiveTab('thisMonth')">本月</div>
  </div>

  <!-- Summary Section -->
  <div class="summary">
    <div class="summary-item" v-for="(item, index) in summaryData" :key="index">
      <div>{
   
   { item.label }}</div>
      <div style="color: #2c5cac; font-size: 18px; font-weight: bold;">{
   
   { item.value }}</div>
    </div>
  </div>

  <!-- Battery Type Rental Ratio -->
  <div class="chart-section">
    <div class="chart-title">电池型号租赁比例</div>
    <div class="chart" ref="donutChart"></div>
  </div>

  <!-- Battery Rental Status -->
  <div class="chart-section">
    <div class="chart-title">电池租赁</div>
    <div class="chart" ref="barChart1"></div>
  </div>

  <!-- Merchant Amount -->
  <div class="chart-section">
    <div class="chart-title">商户佣金</div>
    <div class="chart" ref="barChart2"></div>
  </div>

  <!-- City Transaction Volume -->
  <div class="chart-section">
    <div class="chart-title">城市成交量</div>
    <div class="chart" ref="barChart3"></div>
  </div>
</div>

<script>
  new Vue({
      
      
    el: '#app',
    data: {
      
      
      activeTab: 'yesterday',
      summaryData: [
        {
      
       label: '租赁成交量', value: 49 },
        {
      
       label: '新增租金', value: 3260 },
        {
      
       label: '新增押金', value: 6427 },
        {
      
       label: '用户注册量', value: 86 },
        {
      
       label: '网店注册量', value: 28 },
        {
      
       label: '今日流水', value: 42192 },
      ]
    },
    mounted() {
      
      
      this.initDonutChart();
      this.initBarChart1();
      this.initBarChart2();
      this.initBarChart3();
    },
    methods: {
      
      
      setActiveTab(tab) {
      
      
        this.activeTab = tab;
      },
      initDonutChart() {
      
      
        const donutChart = echarts.init(this.$refs.donutChart);
        const donutOption = {
      
      
          tooltip: {
      
       trigger: 'item' },
          series: [
            {
      
      
              name: '电池型号租赁比例',
              type: 'pie',
              radius: ['40%', '70%'],
              data: [
                {
      
       value: 42, name: '48V12A' },
                {
      
       value: 25, name: '48V20A' },
                {
      
       value: 25, name: '60V20A' },
                {
      
       value: 8, name: '72V20A' }
              ],
              color: ['#66c2ff', '#ffcc66', '#66ff99', '#ff9966']
            }
          ]
        };
        donutChart.setOption(donutOption);
      },
      initBarChart1() {
      
      
        const barChart1 = echarts.init(this.$refs.barChart1);
        const barOption1 = {
      
      
          tooltip: {
      
       trigger: 'axis' },
          xAxis: {
      
       type: 'category', data: ['新租', '换租', '退租'] },
          yAxis: {
      
       type: 'value' },
          series: [
            {
      
      
              data: [568, 303, 124],
              type: 'bar',
              itemStyle: {
      
       color: '#66c2ff' }
            }
          ]
        };
        barChart1.setOption(barOption1);
      },
      initBarChart2() {
      
      
        const barChart2 = echarts.init(this.$refs.barChart2);
        const barOption2 = {
      
      
          tooltip: {
      
       trigger: 'axis' },
          xAxis: {
      
       type: 'category', data: ['安徽', '浙江', '江苏', '山东', '福建', '河南', '湖北', '湖南', '江西', '广西'] },
          yAxis: {
      
       type: 'value' },
          series: [
            {
      
      
              data: [1302, 1100, 1150, 1200, 1400, 1350, 1250, 1500, 1600, 1550],
              type: 'bar',
              itemStyle: {
      
       color: '#ffcc66' }
            }
          ]
        };
        barChart2.setOption(barOption2);
      },
      initBarChart3() {
      
      
        const barChart3 = echarts.init(this.$refs.barChart3);
        const barOption3 = {
      
      
          tooltip: {
      
       trigger: 'axis' },
          xAxis: {
      
       type: 'category', data: ['安徽', '浙江', '江苏', '山东', '福建', '河南', '湖北', '湖南', '江西', '广西'] },
          yAxis: {
      
       type: 'value' },
          series: [
            {
      
      
              data: [1408, 1300, 1250, 1350, 1500, 1450, 1350, 1550, 1450, 1500],
              type: 'bar',
              itemStyle: {
      
       color: '#66ff99' }
            }
          ]
        };
        barChart3.setOption(barOption3);
      }
    }
  });
</script>
</body>
</html>


猜你喜欢

转载自blog.csdn.net/qq_22182989/article/details/143493643