项目引入Echarts.js

  • 安装依赖
- npm install echarts
  • 新增lineChart组件,用来展示折线图
- 准备容器
- 生成echart实例
- 实例.setOption({}) # 一堆的配置...
### Card.lineChart.index.vue

<template>
  <!--容器-->
  <div class="charts" ref="charts"></div>
</template>

<script>
  import echarts from 'echarts';

  export default {
    name: "",
    mounted() {
      // 实例
      let lineCharts = echarts.init(this.$refs.charts);
      // 一堆配置
	  lineCharts.setOption({
	    xAxis: {
	      //隐藏x轴
	      show: false,
	      type: "category",
	    },
	    yAxis: {
	      //隐藏y轴
	      show: false,
	    },
	    //系列
	    series: [
	      {
	        type: "line",
	        data: [10, 7, 33, 12, 48, 9,29,10,44],
	        //拐点的样式的设置(完全透明意味着只展示'顶点')
	        itemStyle: {
	          opacity: 0,
	        },
	        //线条的样式
	        lineStyle: {
	          color: "purple",
	        },
	        //填充颜色设置(弄成渐变的效果)
	        areaStyle: {
	          color: {
	            type: "linear",
	            x: 0,
	            y: 0,
	            x2: 0,
	            y2: 1,
	            colorStops: [
	              {
	                offset: 0,
	                color: "purple", // 0% 处的颜色
	              },
	              {
	                offset: 1,
	                color: "#fff", // 100% 处的颜色
	              },
	            ],
	            global: false, // 缺省为 false
	          },
	        },
	      },
	    ],
	    //布局调试
	    grid: {
	      left: 0,
	      top: 0,
	      right: 0,
	      bottom: 0,
	    },
	  });
    }

  }
</script>

<style scoped>
  .charts {
    width: 100%;
    height: 100%;
  }
</style>

### Card.index.vue 展示折线图

<template>
  <div>
    <el-row :gutter="10">
      <!--总共24个空间-->
      <el-col :span="6">
       ......
      </el-col>

      <el-col :span="6">
        <el-card>
          <Detail title="访问量" count=12306>
            <!--插入组件-->
            <template slot="charts">
              <LineChart></LineChart>
            </template>
            <template slot="footer">
              <span>日访问量1234</span>
            </template>
          </Detail>
        </el-card>
      </el-col>

      <el-col :span="6">
        ......
      </el-col>

      <el-col :span="6">
        ......
      </el-col>

    </el-row>
  </div>
</template>

<script>
  import Detail from './Detail'
  import LineChart from './lineChart'


  export default {
    name:'',
    components:{
      Detail,
      LineChart,
    }
  }
</script>

<style>
</style>

  • 展示饼状图
### Card.barCharts.vue

<template>
  <!-- 容器 -->
  <div class="charts" ref="charts"></div>
</template>

<script>
//引入echarts
import echarts from "echarts";
export default {
  name: "",
  mounted() {
    //初始化echarts实例
    let lineCharts = echarts.init(this.$refs.charts);
    //配置数据
    lineCharts.setOption({
      xAxis: {
        //隐藏x轴
        show: false,
        //均分
        type: "category",
      },
      yAxis: {
        //隐藏y轴
        show: false,
      },
      //系列
      series: [
        {
          //图标形式-柱状图
          type: "bar",
          data: [10, 7, 33, 12, 48, 9,29,10,44],
          color:'cyan'
        },
      ],
      //布局调试
      grid: {
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
      },
      tooltip:{}
    });
  },
};
</script>

<style scoped>
.charts {
  width: 100%;
  height: 100%;
}
</style>

  • 展示进度条图(本质就是饼状图横放效果)
### Card.progressChart.index.vue
<template>
  <!-- 容器 -->
  <div class="charts" ref="charts"></div>
</template>

<script>
//引入echarts
import echarts from "echarts";
export default {
  name: "",
  mounted() {
    //初始化echarts实例
    let lineCharts = echarts.init(this.$refs.charts);
    //配置数据
    lineCharts.setOption({
      xAxis: {
        //隐藏x轴
        show: false,
        //最小值与最大值的设置
        min: 0,
        max: 100,
      },
      yAxis: {
        //隐藏y轴
        show: false,
        //均分
        type: "category",
      },
      //系列
      series: [
        {
          //图标形式-柱状图
          type: "bar",
          data: [78],
          color: "cyan",
          //柱状图的宽度
          barWidth: 10,
          color: "yellowgreen",
          //背景颜色设置
          showBackground: true,
          //设置背景颜色
          backgroundStyle: {
            color: "#eee",
          },
          //文本标签
          label:{
             show:true,
             //改变文本内容
             formatter:'|',
             //文本标签位置调试
             position:'right'
          }
        },
      ],
      //布局调试
      grid: {
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
      },
    });
  },
};
</script>

<style scoped>
.charts {
  width: 100%;
  height: 100%;
}
</style>

  • 结构展示
### Card.index.vue

<template>
  <div>
    <el-row :gutter="10">
      <!--总共24个空间-->
      <el-col :span="6">
        ......
      </el-col>

      <el-col :span="6">
        ......
      </el-col>

      <el-col :span="6">
        <el-card>
          <Detail title="支付笔数" count=12306>
            <template slot="charts">
			  <!--饼状图-->	
              <BarChart></BarChart>
            </template>
            ......
          </Detail>
        </el-card>
      </el-col>

      <el-col :span="6">
        <el-card>
          <Detail title="运营活动效果" count=78%>
            <template slot="charts">
			  <!--进度条图-->		
              <ProgressChart></ProgressChart>
            </template>
            ......
          </Detail>
        </el-card>
      </el-col>

    </el-row>
  </div>
</template>

<script>
  import Detail from './Detail'
  import LineChart from './lineChart'
  import ProgressChart from './progressChart'
  import BarChart from './barCharts'

  export default {
    name:'',
    components:{
      Detail,
      LineChart,
      ProgressChart,
      BarChart
    }
  }
</script>

<style>
</style>

首页中间部分(销售额)

  • 新建Sale组件
### dashboard.Sale.index.vue

<template>
  <div></div>
</template>

<script>
  export default {
    name: 'Sale'
  }
</script>

<style>
  
</style>

### dashboard.index.vue

<template>
  <div>
    <Card></Card>
    <!--运用-->
    <Sale></Sale>
  </div>
</template>

<script>
......
import Sale from './Sale'

export default {
  name: 'Dashboard',
  components:{
    Card,
    Sale // 注册
  },
}
</script>

<style lang="scss" scoped>
......
</style>


  • 完成Sale组件的头部

<template>
  <el-card class="box-card" style="margin: 10px 0px;">
	<!--头部内容-->
    <div slot="header" class="clearfix">
	  <!--头部左侧tab标签-->	
      <!--v-model="activeName" @tab-click="handleClick"-->
      <el-tabs class="tab">
        <el-tab-pane label="销售量" name="first"></el-tab-pane>
        <el-tab-pane label="访问量" name="second"></el-tab-pane>
      </el-tabs>
      
      <!--头部右侧日期-->
      <div class="right">
        <span>今日</span>
        <span>本周</span>
        <span>本月</span>
        <span>本年</span>
        <!--v-model="value2" align="right" unlink-panels :picker-options="pickerOptions"-->
        <el-date-picker  type="daterange" range-separator="-" size="mini"
          start-placeholder="开始日期" end-placeholder="结束日期" class="date">
        </el-date-picker>
      </div>
    </div>

  </el-card>
</template>

<script>
  export default {
    name: 'Sale'
  }
</script>

<style>
  .el-card__header {
    /*消除底部横线*/
    border-bottom: none;
  }
</style>

<style scoped>
  /*把头部项目分为左右两块内容*/	
  .clearfix {
    position: relative;
    display: flex;
    justify-content: space-between;
  }
  /*拓展tab标签横线*/
  .tab {
    width: 100%;
  }

  /*把日期固定在右边*/
  .right {
    position: absolute;
    right: 0px;
  }
  /*日期大小,间隔*/
  .date {
    width: 200px;
    margin: 0px 20px;
  }
  .right span {
    margin: 0px 10px;
  }
</style>

  • 完成Sale组件中间部分
<template>
  <el-card class="box-card" style="margin: 10px 0px;">
    <div slot="header" class="clearfix">
      ......
    </div>

    <!--中间部分-->
    <div>
	  <!--echart图表占据18空间,剩余给销售额-->
      <el-row :gutter="10">
        <!--echarts图表,准备容器-->
        <el-col :span="18">
          <div class="charts" ref="charts"></div>
        </el-col>

        <!--排行榜-->
        <el-col :span="6" class="right">
          <h3>门店销售额排名</h3>
          <ul>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
            <li>
              <span class="rindex">0</span>
              <span>肯德基</span>
              <span class="rvalue">123456</span>
            </li>
          </ul>
        </el-col>
      </el-row>
    </div>
  </el-card>
</template>

<script>
  import echarts from "echarts"

  export default {
    name: 'Sale',
    ......
    mounted() {
	  // 生成echart实例并配置(官网找示例,照抄即可)	
      let mycharts = echarts.init(this.$refs.charts)
      mycharts.setOption({
        title:{
          text:'销售趋势'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [{
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
          axisTick: {
            alignWithLabel: true
          }
        }],
        yAxis: [{
          type: 'value'
        }],
        series: [{
          name: 'Direct',
          type: 'bar',
          barWidth: '60%',
          data: [10, 52, 200, 334, 390, 330, 220]
        }]
      })
    }
  }
</script>

<style>
  .el-card__header {
    /*消除底部横线*/
    border-bottom: none;
  }
</style>

<style scoped>
  .clearfix {
    position: relative;
    display: flex;
    justify-content: space-between;
  }

  /*拓展横线*/
  .tab {
    width: 100%;
  }

  /*把日期固定在右边*/
  .right {
    position: absolute;
    right: 0px;
  }

  .date {
    width: 200px;
    margin: 0px 20px;
  }

  .right span {
    margin: 0px 10px;
  }

  .charts {
    width: 100%;
    height: 300px;
  }
  /*列表的样式*/
  ul {
    list-style: none;
    width: 100%;
    height: 300px;
    padding: 0px;
  }
  ul li {
    height: 8%;
  }
  /*序号美化*/
  .rindex {
    float: left;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: black;
    color: white;
    text-align: center;
  }
  /*右边的销售数据*/
  .rvalue {
    float: right;
  }
</style>
  • 优化tab标签切换时,销售量访问量之间的title提示
### Sale.index.vue
......
<el-tabs class="tab" v-model="activeName">
    <!--name属性收集到的值,传给activeName-->
    <el-tab-pane label="销售量" name="sale"></el-tab-pane>
    <el-tab-pane label="访问量" name="visit"></el-tab-pane>
</el-tabs>
......
<el-col :span="6" class="right">
    <!--动态值-->
    <h3>门店{{title}}排名</h3>
......
data() {
	return {
		activeName: 'sale',	 // 设置默认值
		mycharts:null // 初始化值(之前在mouted加载的,但是只能执行一次,不满足切换标签就修改值的需求)
	}
},
computed:{
	title(){ // 动态计算title值
		return this.activeName == 'sale' ? '销售量' : '访问量'
	}
},
watch:{
  title(){ // 监视title值的改变,跟着变
	this.mycharts.setOption({
	  title:{
		text:this.title
	  }
	})
  }
},
mounted() {
  this.mycharts = echarts.init(this.$refs.charts) // 修改为使用data中的值
  this.mycharts.setOption({
	title:{
	  text:'销售趋势'
	},
	tooltip: {.......}
}
  • 实现点击今日,本周,本月,本年,日期组件自动填充对应的日期(以获取今日为例)
- npm install dayjs # 优化日期格式

### Sale.index.vue

......
<div class="right">
	<!--绑定点击事件-->
	<span @click="setDay">今日</span>
	<span>本周</span>
	<span>本月</span>
	<span>本年</span>

	<!--v-model收集用户输入,value-format格式化日期-->
	<el-date-picker type="daterange" range-separator="-" size="mini" start-placeholder="开始日期" end-placeholder="结束日期"
	  class="date" v-model="date" value-format="yyyy-MM-dd">
	</el-date-picker>
</div>
......
<script>
	......
  import dayjs from 'dayjs'

  export default {
    name: 'Sale',
    data() {
      return {
        ......
        // 初始化值(收集到的数据格式是这样的['1999-08-06','1999-09-10'])
        date:[]
      }
    },
    methods:{
      setDay(){
        const day = dayjs().format('YYYY-MM-DD') // 获取今天
        this.date = [day,day] // 赋值给日期组件并展示
      }
    },
  • 获取本周,本月,本年
......
methods:{
  ......
  // 设置本周
  setWeek(){
	const start = dayjs().day(1).format('YYYY-MM-DD')
	const end = dayjs().day(7).format('YYYY-MM-DD')
	this.date = [start,end]
  },
  // 设置本月
  setMonth(){
	const start = dayjs().startOf('month').format('YYYY-MM-DD')
	const end = dayjs().endOf('month').format('YYYY-MM-DD')
	this.date = [start,end]
  },
  // 设置本年
  setYear(){
	const start = dayjs().startOf('year').format('YYYY-MM-DD')
	const end = dayjs().endOf('year').format('YYYY-MM-DD')
	this.date = [start,end]
  }
},

首页底部内容的开发

  • 新增Observe组件,用来展示底部内容
### dashboard.Observe.index.vue

<template>
  <div>我是observe组件的内容</div>
</template>

<script>
  export default {
    name:''
  }
</script>

<style>
</style>

### dashboard.index.vue

<template>
  <div>
    <Card></Card>
    <Sale></Sale>
    <!--使用-->
    <Observe></Observe>
  </div>
</template>

<script>
......
import Observe from './Observe'

export default {
  name: 'Dashboard',
  components:{
   ......
    Observe // 注册
  }
}
</script>
  • 继续拆分 Observe组件Search组件Category组件
### Observe.Search.index.vue

<template>
  <div>我是Search组件的内容</div>
</template>

<script>
  export default {
    name:''
  }
</script>

<style>
</style>

### Observe.Category.index.vue

<template>
  <div>我是Category组件的内容</div>
</template>

<script>
  export default {
    name:''
  }
</script>

<style>
</style>

### Observe.index.vue

<template>
  <div>
    <el-row :gutter="10">
      <!--每个组件都各自占一半空间-->
      <el-col :span="12">
        <Search></Search>
      </el-col>

      <el-col :span="12">
        <Category></Category>
      </el-col>
    </el-row>
  </div>
</template>

<script>
  import Search from './Search'
  import Category from './Category'

  export default {
    name:'',
    components:{
      Search,
      Category
    }
  }
</script>

<style>
</style>

  • 搞定Search组件的头部内容
### Search.index.vue

<template>
  <el-card>
    <!--头部-->
    <div slot="header">
      <div class="search-header">
        <span>线上热门搜索</span>
        <i class="el-icon-more"></i>
      </div>
    </div>
    <!--头部下面的内容-->
    <div></div>
  </el-card>
</template>

<script>
  export default {
    name:''
  }
</script>

<style scoped>
  .search-header {
    display: flex;
    justify-content: space-between; /*两块元素分隔两侧*/
  }
</style>

  • 新增LineCharts组件并复用
### Search.LineCharts.index.vue

<template>
  <div>我是LineCharts的内容</div>
</template>

<script>
  export default {
    name:''
  }
</script>

<style>
</style>

### Search.index.vue

<template>
  <el-card>
    <!--头部-->
    <div slot="header">
      ......
    </div>
    <!--头部下面的内容-->
    <div>
      <el-row :gutter="10">
        <el-col :span="12">
          <!--运用-->
          <LineCharts></LineCharts>
        </el-col>

        <el-col :span="12">
          <!--复用-->
          <LineCharts></LineCharts>
        </el-col>
      </el-row>
    </div>
  </el-card>
</template>

<script>
  import LineCharts from './LineCharts'

  export default {
    name:'',
    components:{
      LineCharts
    }
  }
</script>

<style scoped>
  ......
</style>

  • 补充一下头部下面的横线样式
### Search.index.vue

<template>
  <el-card>
    <!--新增header类名-->
    <div slot="header" class="header">
      ......
    </div>
	
    <div>
      ......
    </div>
  </el-card>
</template>

<script>
  ......
</script>

<style scoped>
  ......
  .header { /*增加横线样式*/
    border-bottom: 1px solid #eee;
    padding: 5px 0px;
  }
</style>

  • 修改...符号为下拉菜单(鼠标移动过去,立马展示下拉菜单,elementUI有提供)
### Search.index.vue
......
	<!--头部-->
    <div slot="header" class="header">
      <div class="search-header">
        <span>线上热门搜索</span>
        <el-dropdown>
          <span>
            <!--之前的标签移动到这边-->
            <i class="el-icon-more"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>黄金糕</el-dropdown-item>
            <el-dropdown-item>狮子头</el-dropdown-item>
            <el-dropdown-item>螺蛳粉</el-dropdown-item>
            <el-dropdown-item>双皮奶</el-dropdown-item>
            <el-dropdown-item>蚵仔煎</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </div>
  • echarts部分
### LineCharts.index.vue

<template>
  <div>
	<!--头部-->
    <div class="header">
      <span class="search-header">搜索用户数</span>
      <svg t="1692932780198" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4025" width="16" height="16"><path d="M468.394667 936.448a427.946667 427.946667 0 0 1-42.368-6.485333 431.488 431.488 0 0 1-80.085334-24.832 426.368 426.368 0 0 1-72.533333-39.338667 429.312 429.312 0 0 1-63.146667-52.096 429.269333 429.269333 0 0 1-52.096-63.146667 426.666667 426.666667 0 0 1-39.338666-72.533333 418.602667 418.602667 0 0 1-24.832-80.085333 425.429333 425.429333 0 0 1-6.485334-42.368A434.474667 434.474667 0 0 1 85.333333 512a434.517333 434.517333 0 0 1 2.218667-43.605333 425.514667 425.514667 0 0 1 6.485333-42.368 431.488 431.488 0 0 1 24.832-80.085334 426.666667 426.666667 0 0 1 39.338667-72.533333 429.312 429.312 0 0 1 52.096-63.146667 429.44 429.44 0 0 1 63.146667-52.096 426.325333 426.325333 0 0 1 72.533333-39.338666 418.602667 418.602667 0 0 1 80.085333-24.832 427.349333 427.349333 0 0 1 42.368-6.485334A433.194667 433.194667 0 0 1 512 85.333333a433.493333 433.493333 0 0 1 43.605333 2.218667 427.818667 427.818667 0 0 1 42.368 6.485333 431.488 431.488 0 0 1 80.085334 24.832 426.666667 426.666667 0 0 1 72.533333 39.338667 429.909333 429.909333 0 0 1 63.146667 52.096 429.866667 429.866667 0 0 1 52.096 63.146667 426.666667 426.666667 0 0 1 39.338666 72.533333c5.418667 12.8 10.24 25.984 14.336 39.210667s7.68 27.136 10.538667 40.874666 5.034667 28.16 6.442667 42.368A431.488 431.488 0 0 1 938.666667 512a431.445333 431.445333 0 0 1-2.218667 43.605333 428.458667 428.458667 0 0 1-6.442667 42.368 419.114667 419.114667 0 0 1-24.874666 80.085334 426.666667 426.666667 0 0 1-39.338667 72.533333 429.781333 429.781333 0 0 1-52.096 63.146667 429.866667 429.866667 0 0 1-63.146667 52.096 426.666667 426.666667 0 0 1-72.533333 39.338666 414.293333 414.293333 0 0 1-80.085333 24.832 428.416 428.416 0 0 1-42.368 6.485334A433.493333 433.493333 0 0 1 512 938.666667a433.194667 433.194667 0 0 1-43.605333-2.218667zM145.066667 512a367.36 367.36 0 0 0 366.933333 366.933333 367.36 367.36 0 0 0 366.933333-366.933333A367.36 367.36 0 0 0 512 145.066667 367.36 367.36 0 0 0 145.066667 512z m270.933333 250.666667v-59.733334h66.133333V416H424.533333v-59.733333h117.333334v346.666666h66.133333v59.733334zM482.133333 322.133333v-59.733333h59.733334v59.733333z" p-id="4026"></path></svg>
    </div>
	<!--中间部分-->
    <div class="main">
      <span class="main-title">12312</span>
      <span class="main-content">666</span>
      <svg t="1692935225089" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6581" width="16" height="16"><path d="M335 546.6V117.1c0-54.8 44.5-99.3 99.3-99.3h165.4c54.8 0 99.3 44.5 99.3 99.3v429.5h264.7l-446.9 463L70 546.6h265z m0 0" fill="#d81e06" p-id="6582"></path></svg>
      <svg t="1692935095365" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5389" width="16" height="16"><path d="M698.7 480.9v429.5c0 54.8-44.5 99.3-99.3 99.3H434c-54.8 0-99.3-44.5-99.3-99.3V480.9H70l446.9-463 446.9 463H698.7z m0 0" fill="#1afa29" p-id="5390"></path></svg>
    </div>
	<!--尾部插入表格-->
    <div class="footer">
      <div class="charts" ref="charts"></div>
    </div>
  </div>
</template>

<script>
  import echarts from 'echarts';

  export default {
    name:'',

    mounted() {
      let lineCharts = echarts.init(this.$refs.charts);
      lineCharts.setOption({
        xAxis: {
          //隐藏x轴
          show: false,
          type: "category",
        },
        yAxis: {
          //隐藏y轴
          show: false,
        },
        //系列
        series: [{
          type: "line",
          data: [10, 7, 33, 12, 48, 9, 29, 10, 44, 66, 77, 88, 99],
          //拐点的样式的设置(完全透明意味着只展示'顶点')
          itemStyle: {
            opacity: 0,
          },
          //线条的样式
          lineStyle: {
            color: "orange",
          },
          //填充颜色设置(弄成渐变的效果)
          areaStyle: {
            color: {
              type: "linear",
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [{
                  offset: 0,
                  color: "green", // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: "#fff", // 100% 处的颜色
                },
              ],
              global: false, // 缺省为 false
            },
          },
        }, ],
        //布局调试
        grid: {
          left: 0,
          top: 0,
          right: 0,
          bottom: 0,
        },
      });
    }
  }
</script>

<style scoped>
  .header {
    display: flex;
    align-items: center;
  }
  .search-header {
    margin-right: 10px;
  }
  .main {
    margin: 10px 0px;
  }
  .main-title {
    margin-right: 30px;
  }
  .main-content {
    margin-right: 10px;
  }
  .charts {
    width: 100%;
    height: 50px;
  }
</style>

  • table表格部分
### Search.index.vue
......
<div>
  <!--echarts部分-->
  <el-row :gutter="10">
	......
  </el-row>
  <!--表格部分-->
  <el-table :data="tableData" style="width: 100%" border="">
	<el-table-column label="排名" width="80" type="index">
	</el-table-column>
	<el-table-column label="搜搜关键字" width="180">
	</el-table-column>
	<el-table-column label="用户数" sortable>
	</el-table-column>
	<el-table-column label="周涨幅" sortable>
	</el-table-column>
  </el-table>

</div>
......
<script>
  import LineCharts from './LineCharts'

  export default {
    ......
    data(){
      return {
        tableData:[{}] // 初始化数据
      }
    }
  }
</script>
  • 分页器部分
<div>
  <!--echarts部分-->
  <el-row :gutter="10">
	......
  </el-row>
  <!--表格部分-->
  <el-table :data="tableData" style="width: 100%" border="">
	......
  </el-table>
  <!--分页器-->
  <el-pagination layout="prev, pager, next" :total="1000" class="pagination">
  </el-pagination>
</div>
......
<style scoped>
  ......
  .pagination {
    float: right;
  }
</style>

Category组件部分

### Category.index.vue

<template>
  <el-card>
    <!--头部-->
    <div slot="header" class="header">
      <div class="category-header">
        <span>销售额类别占比</span>
        <el-radio-group v-model="value">
            <el-radio-button label="上海"></el-radio-button>
            <el-radio-button label="北京"></el-radio-button>
            <el-radio-button label="广州"></el-radio-button>
            <el-radio-button label="深圳"></el-radio-button>
        </el-radio-group>
      </div>
    </div>
    <!--头部下面的内容(echarts)-->
    <div>
      <div class="charts" ref="charts"></div>
    </div>
  </el-card>
</template>

<script>
  import echarts from 'echarts'

  export default {
    name:'',
    data(){
      return {
        value:'全部渠道'
      }
    },
    mounted() {
      //饼图
      let mychart = echarts.init(this.$refs.charts);
      mychart.setOption({
        title: {
          text: "视频",
          subtext: 1048,
          left: "center",
          top: "center",
        },
        tooltip: {
          trigger: "item",
        },
        series: [
          {
            name: "Access From",
            type: "pie",
            radius: ["40%", "70%"],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 10,
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: true,
              position: "outsize",
            },
            labelLine: {
              show: true,
            },
            data: [
              { value: 1048, name: "视频" },
              { value: 735, name: "Direct" },
              { value: 580, name: "Email" },
              { value: 484, name: "Union Ads" },
              { value: 300, name: "Video Ads" },
            ],
          },
        ],
      });
      //绑定事件

      mychart.on("mouseover",(params)=>{
          //获取鼠标移上去那条数据
          const {name,value} = params.data;
          //重新设置标题
          mychart.setOption({
            title:{
              text:name,
              subtext:'value'
            }
          })
      });
    },
  }
</script>

<style scoped>
  .category-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .header {
    border-bottom: 1px solid #eee;
  }
  .charts {
    width: 100%;
    height: 300px;
  }
</style>

mock模拟数据

  • 先准备数据源
### mock.data.json

{
  "salesTotal":114779,
  "salesToday":112356,
  "salesGrowthLastDay": -19.16,
  "salesGrowthLastMonth": 56.67,

  "visitTotal": 88460,
  "visitToday": 1234,
  "visitTrend": [
    610,
    432,
    220,
    534,
    790,
    430,
    220,
    320,
    532,
    320,
    834,
    690,
    530,
    220,
    620
  ],

  "payTotal": 182425,
  "payRate": 60.2,
  "payTrend": [
    410,
    82,
    200,
    334,
    390,
    330,
    220,
    150,
    82,
    200,
    134,
    290,
    330,
    150
  ],

  "activityRate": 78,
  "activityGrowthLastDay": -17.7,
  "activityGrowthLastMonth": 47.12,

  "orderFullYearAxis": [
    "1月",
    "2月",
    "3月",
    "4月",
    "5月",
    "6月",
    "7月",
    "8月",
    "9月",
    "10月",
    "11月",
    "12月"
  ],
  "orderFullYear": [410, 82, 200, 334, 390, 330, 220, 150, 82, 200, 134, 290],
  "userFullYearAxis": [
    "1月",
    "2月",
    "3月",
    "4月",
    "5月",
    "6月",
    "7月",
    "8月",
    "9月",
    "10月",
    "11月",
    "12月"
  ],
  "userFullYear": [110, 120, 90, 220, 175, 212, 192, 95, 88, 120, 250, 310],

  "orderRank": [
    {
      "no": 1,
      "name": "肯德基",
      "money": "323,234"
    },
    {
      "no": 2,
      "name": "麦当劳",
      "money": "299,132"
    },
    {
      "no": 3,
      "name": "肯德基",
      "money": "283,998"
    },
    {
      "no": 4,
      "name": "海底捞",
      "money": "266,223"
    },
    {
      "no": 5,
      "name": "西贝筱面村",
      "money": "223,445"
    },
    {
      "no": 6,
      "name": "汉堡王",
      "money": "219,663"
    },
    {
      "no": 7,
      "name": "真功夫",
      "money": "200,997"
    }
  ],

  "userRank": [
    {
      "no": 1,
      "name": "麦当劳",
      "money": "211,335"
    },
    {
      "no": 2,
      "name": "肯德基",
      "money": "210,597"
    },
    {
      "no": 3,
      "name": "必胜客",
      "money": "200,998"
    },
    {
      "no": 4,
      "name": "海底捞",
      "money": "199,220"
    },
    {
      "no": 5,
      "name": "西贝筱面村",
      "money": "195,444"
    },
    {
      "no": 6,
      "name": "汉堡王",
      "money": "180,161"
    },
    {
      "no": 7,
      "name": "真功夫",
      "money": "172,995"
    }
  ],

  "searchWord": [
    {
      "word": "北京",
      "count": 3440,
      "user": 1626
    },
    {
      "word": "上海",
      "count": 8101,
      "user": 6660
    },
    {
      "word": "广州",
      "count": 7814,
      "user": 2196
    },
    {
      "word": "深圳",
      "count": 8888,
      "user": 7102
    },
    {
      "word": "南京",
      "count": 6204,
      "user": 1949
    },
    {
      "word": "杭州",
      "count": 8159,
      "user": 3548
    },
    {
      "word": "合肥",
      "count": 269,
      "user": 151
    },
    {
      "word": "济南",
      "count": 2045,
      "user": 1320
    },
    {
      "word": "太原",
      "count": 5693,
      "user": 2297
    },
    {
      "word": "成都",
      "count": 4850,
      "user": 1635
    },
    {
      "word": "重庆",
      "count": 906,
      "user": 269
    },
    {
      "word": "苏州",
      "count": 5576,
      "user": 3937
    },
    {
      "word": "无锡",
      "count": 1576,
      "user": 796
    },
    {
      "word": "常州",
      "count": 9002,
      "user": 8508
    },
    {
      "word": "温州",
      "count": 8103,
      "user": 4903
    },
    {
      "word": "哈尔滨",
      "count": 7961,
      "user": 6173
    },
    {
      "word": "长春",
      "count": 5916,
      "user": 3117
    },
    {
      "word": "大连",
      "count": 5012,
      "user": 78
    },
    {
      "word": "沈阳",
      "count": 8410,
      "user": 5696
    },
    {
      "word": "拉萨",
      "count": 3385,
      "user": 2547
    },
    {
      "word": "呼和浩特",
      "count": 4672,
      "user": 34
    },
    {
      "word": "武汉",
      "count": 7386,
      "user": 4047
    },
    {
      "word": "南宁",
      "count": 6192,
      "user": 612
    },
    {
      "word": "必胜客",
      "count": 3504,
      "user": 2480
    },
    {
      "word": "肯德基",
      "count": 3727,
      "user": 2527
    },
    {
      "word": "麦当劳",
      "count": 8959,
      "user": 6198
    },
    {
      "word": "海底捞",
      "count": 5295,
      "user": 2264
    },
    {
      "word": "美食",
      "count": 7348,
      "user": 5555
    },
    {
      "word": "商超",
      "count": 1628,
      "user": 1295
    },
    {
      "word": "水果",
      "count": 892,
      "user": 215
    },
    {
      "word": "跑腿",
      "count": 254,
      "user": 40
    },
    {
      "word": "送药",
      "count": 8377,
      "user": 4363
    },
    {
      "word": "烩饭",
      "count": 2009,
      "user": 1080
    },
    {
      "word": "面条",
      "count": 7684,
      "user": 4299
    },
    {
      "word": "小龙虾",
      "count": 3187,
      "user": 562
    },
    {
      "word": "牛肉",
      "count": 3612,
      "user": 3449
    },
    {
      "word": "鸡腿",
      "count": 4460,
      "user": 367
    },
    {
      "word": "全家桶",
      "count": 7206,
      "user": 3682
    },
    {
      "word": "麦乐鸡",
      "count": 3383,
      "user": 3048
    },
    {
      "word": "炭烤",
      "count": 8818,
      "user": 26
    },
    {
      "word": "麻辣",
      "count": 1297,
      "user": 905
    },
    {
      "word": "冒菜",
      "count": 3015,
      "user": 2362
    }
  ],

  "saleRank": {
    "online": {
      "name": [
        "家用电器",
        "食用酒水",
        "个护健康",
        "服饰箱包",
        "母婴产品",
        "其他"
      ],
      "value": [244, 321, 301, 41, 111, 69]
    },
    "shop": {
      "name": [
        "家用电器",
        "食用酒水",
        "个护健康",
        "服饰箱包",
        "母婴产品",
        "其他"
      ],
      "value": [68, 15, 41, 56, 70, 25, 31]
    }
  }
}

  • 配置数据源和请求路径
### mock.home.js

const data = require('./data.json');
module.exports = [
  {
    url: '/home/list',
    type: 'get',
    response: config => {
      const items = data.items
      return {
        code: 20000,
        data
      }
    }
  }
]

  • 注册home模块
### mock.index.js

......
const table = require('./table')
const home = require('./home') // 模仿上面的写法

const mocks = [
  ...user,
  ...table,
  ...home // 注册
]
  • 在当前项目中开启mock(之前的是把它删掉了)
### vue.config.js
......
//配置代理跨域
proxy: {
  ......
},
// 开启mock数据
before: require('./mock/mock-server.js')
  • 修改mock-server.js.env.development的配置
### mock-server
......
// for mock server
const responseFake = (url, type, respond) => {
  return {
    // url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
    // 修改 API 名称
    url: new RegExp(`${process.env.VUE_APP_MOCK_API}${url}`),
    ......
    }
  }
}

### .env.development
......
# base api
VUE_APP_BASE_API = '/dev-api'
// 新增
VUE_APP_MOCK_API = '/mock-api' 



  • 模仿utils.request.js写法,新增mockRequest.js
import axios from 'axios'
......
const service = axios.create({
 // API名称修改一下
  baseURL: process.env.VUE_APP_MOCK_API,
  ......
})
......
  • vuex中,搞定home仓库
### store.modules.home.js
const state = {};
const mutations = {};
const actions = {};
const getters = {};

export default {
  state,
  mutations,
  actions,
  getters
}

### store.index.js 注册 home 模块
......
import home from './modules/home'
Vue.use(Vuex)
const store = new Vuex.Store({
  modules: {
  ......
    home
  },
  getters
})
......

  • 测试能否正常获取mock数据
### store.modules.home.js
import mockRequest from '@/utils/mockRequest'
......
const actions = {
  async getData({commit}){
    let res = await mockRequest.get('/home/list')
    console.log(res)
  }
};
......

### dashboard.index.vue (测试结果: 正常返回了数据)
......
mounted(){
    this.$store.dispatch('getData')
  }
	
  • 存储mock数据
### store.modules.home.js
import mockRequest from '@/utils/mockRequest'

const state = {
  list:{} // 初始化,存储数据
};
const mutations = {
  GETDATA(state,list){
    state.list = list // 存储
  }
};
const actions = {
  async getData({commit}){
    let res = await mockRequest.get('/home/list')
    if(res.code == 20000){
      commit("GETDATA",res.data) // 提交到mutations
    }
  }
};
const getters = {};

export default {
  state,
  mutations,
  actions,
  getters
}

  • Sale组件为例,使用mock数据来填充
### Sale.index.vue
......
<script>
  ......
  import {magState, mapState} from 'vuex'

  export default {
    name: 'Sale',
    ......
    methods:{
      ......
    },
    computed:{
      ......
	  // 映射仓库的数据
      ...mapState({
        listState:state=>state.home.list
      })
    },
    watch:{
      title(){
        this.mycharts.setOption({
          title:{
            text:this.title
          },
          xAxis:{
            // data:this.title == "销售额"?this.listState.orderFullYearAxis:this.listState.userFullYearAxis
			// 填充数据
            data:this.listState.orderFullYearAxis
          },
          series: [{
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            // data: this.title == "销售额"?this.listState.orderFullYearAxis:this.listState.userFullYearAxis
			// 填充数据
            data:this.listState.orderFullYearAxis
          }]
        })
      },
    },
    mounted() {
      this.mycharts = echarts.init(this.$refs.charts)
      this.mycharts.setOption({
        ......
        xAxis: [{
          type: 'category',
          // data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
		  // 清空数据
          data: [],
          ......
        }],
        ......
        series: [{
          name: 'Direct',
          type: 'bar',
          barWidth: '60%',
          // data: [10, 52, 200, 334, 390, 330, 220]
		  // 清空数据
          data: []
        }]
      })
    }
  }
</script>
  • 项目测试结果: 在登录页面卡主了,暂时的解决办法是,取消mock配置
### vue.config.js
......
proxy: {
      '/dev-api': {
        target:"http://gmall-h5-api.atguigu.cn",
        pathRewrite: { '^/dev-api':'' },
      },
    },
    // 注释掉mock数据
    // before: require('./mock/mock-server.js')