vue多组件通讯,应用echarts展示数据

150 阅读3分钟

今天总结一下工作时开发的一个页面,内容非常基础,主要是边学边干所以记录一下,以便将来忘了查阅方便。

0、架构介绍

页面如下所示,主要是从数据库获取到完整性评价信息后,分别以左、右、下三个子组件展示数据,其中右侧组件应用echarts柱状图插件对数据进行展示。

image.png

该页面程序建立了三个子组件,文件结构如下所示

image.png

barChart和detail是右侧柱状图,pm是左侧的周期排序,wzxlevel是底部详细信息,半年前做的页面一直懒得归纳,现在我也有点记不清了,这里大部分都比较简单好实现,主要是echarts那里比较麻烦。

开发过程分为以下几步:

  1. 顶部组件选择评价批次,通过jquery获取储罐完整性数据;
  2. 父组件接收到数据后进行存储,转发到各组件中;
  3. 各组件接收数据,进行数据展示。

1、获取数据

数据获取部分首先通过下拉栏选择批次内容,将内容传给后端,根据批次名称获取数据,比较简单,代码如下。

<el-card shadow="always" style="margin: 20px 10px">
      <el-form :inline="true" :model="searchInfo">
        <el-form-item label="选择评价批次:">
          <el-select v-model="searchInfo.batch_name" placeholder="请选择" @change="search">
            <el-option :label="c2.batchName" :value="c2.batchName" v-for="c2 in this.batchList" :key="c2.batchName">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </el-card>

el-form中有一个下拉栏一个按钮,按钮负责批次管理,这里不展示,下拉栏选择好批次后通过@change直接运行函数search进行数据存储,search函数代码如下。

 async search(){
      this.jc=[]
      this.gb=[]
      this.gbfj=[]
      this.fd=[]
      this.fdfj=[]
      this.zf=[]
      this.tankId=[]
      const result = await this.$API.getBatchList.getTankScore(this.searchInfo);
      this.batchInfo = result.data.items;
    }

清空数据后,通过异步获取searchInfo,并存入items中。

2、父组件传值子组件

左侧与底部的table较为简单,如下所示,柱状图单独说明。

左侧
      <el-col :span="8">
        <el-card class="pm1">
          <pm v-bind:value="this.batchInfo"></pm>
        </el-card>
      </el-col>
底部
    <el-row :gutter="10">
      <el-col :span="24">
        <el-card style="margin:20px">
          <wzxlevel v-bind:value="this.batchInfo"></wzxlevel>
        </el-card>
      </el-col>
    </el-row>

其中<pm><wzxlevel>分别对应上面建立的两个子组件,通过v-bind:value="this.batchInfo"的方式,值就传过去了。 柱状图就比较特殊了,我比较菜,不记得原理了,只是这么做是好用的。

      <el-col :span="16">
        <el-card class="barcharts">
          <detail>
            <template slot="charts">
              <barCharts :value="this.batchInfo"></barCharts>
            </template>
          </detail>
        </el-card>
      </el-col>

写到这里我才发现,我的写法可能是有问题的。首先给该区域写了一个类"barcharts",然后放入一个子组件detail,然后在里面加了一个作用域插槽"charts",在这个模板中再放入了barCharts组件并传入数据,此时barCharts组件就能收到数据了,detail组件中代码如下所示:

<template>
        <div class="barcharts">
            <slot name="charts"></slot>
        </div>
</template>

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

我还尝试了下面的写法:

      <el-col :span="16">
        <el-card class="barcharts">
              <barCharts :value="this.batchInfo"></barCharts>
        </el-card>
      </el-col>

这样子组件无法收到数据,不知道是为什么,要是有好心大佬还望不吝赐教。

3、数据展示

最后是子组件接收并展示数据,同样的,先将好做的pm和wzxlevel做好,此处只以pm为例。

<template>
  <el-table :data="value" style="width: 100%" :default-sort="{ prop: 'totalScore', order:'ascending'}" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
    <el-table-column type="index" label="优先级" width="80px">
    </el-table-column>
    <el-table-column prop="tankId" label="储罐编号">
    </el-table-column>
    <el-table-column prop="totalScore" label="完整性评分">
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  props:['value']
};
</script>

<style>
</style>

export default中的value就是父组件传来的"this.batchInfo",直接放到table中进行展示,并进行升序排列。

echarts这里我记得调试了一个晚上,主要是传值过不来。首先写好一个div,用于装echarts。

<template>
    <div class="charts" ref="charts"></div>
</template>

echarts算是比较好用,只要在script中引入echarts就可以使用了。 import * as echarts from 'echarts' 然后是接收数据,接收这里就是和别的组件不一样的地方了: props: ['value'], 然后应用了侦听器watch进行数据接收:

watch: {
        //jc1
        value: {
            handler(newVal, oldVal) {//newVal为新传入数据,oldVal为当前数据或上一次
                //此处给监听的对象加一个条件,防止空值进入
                if (newVal !== undefined) {
                    // this.jc2 = newVal
                    this.jc2 = []
                    this.gb2 = []
                    this.gbfj2 = []
                    this.fd2 = []
                    this.fdfj2 = []
                    this.zf2 = []
                    this.tankId2 = []
                    for (var i = 0; i < newVal.length; i++) {
                        this.jc2[i] = newVal[i].basicScore
                        this.gb2[i] = newVal[i].wallScore
                        this.gbfj2[i] = newVal[i].wallAccessoriesScore
                        this.fd2[i] = newVal[i].roofScore
                        this.fdfj2[i] = newVal[i].roofAccessoriesScore
                        this.zf2[i] = newVal[i].totalScore
                        this.tankId2[i] = newVal[i].tankId
                    }
                    this.init();
                }
            },
            deep: true,//深度监听开启
        }
    },

将之前的数据清空,然后存入新值,接下来是钩子函数,在页面dom刷新时刷新柱状图。

mounted() {
        this.barCharts = echarts.init(this.$refs.charts);
        this.init()
    },

这里记不清了,echarts.init好像是初始化柱状图,规定好柱状图的颜色,几个值之类的。init就是重新绘制柱状图,init()代码如下所示,比较多我就删掉一些重复的部分:

init() {
            this.barCharts.clear();
            this.barCharts.setOption({
                title: {
                    text: '储罐完整性评分总览',
                },
                tooltip: {
                    trigger: 'axis'
                },
                legend: {
                    data: ['基础', '罐壁', '罐壁附件', '浮顶', '浮顶附件', '总分']
                },
                toolbox: {
                    show: false,
                    feature: {
                        magicType: { show: true, type: ['stack', 'tiled'] },
                        saveAsImage: { show: true }
                    }
                },
                xAxis: {
                    title: '储罐编号',
                    data: this.tankId2
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                    {
                        name: '总分',
                        type: 'bar',
                        stack: 'asdf',
                        color: '#FFF',
                        label: {
                            show: true,
                            position: 'top',
                            color: '#000'
                        },
                        barGap: '-100%',
                        data: this.zf2
                    }
                ],
            });
        }

这里主要涉及的是echarts中的用法,我认为不需要记,用的时候去官网现查就可以了。

以上就是这个页面的全部开发过程,写到这里心里有一些感慨,入职前我只是一个普通的一本硕士生,会一些C#开发、神经网络和遗传算法。刚入职时心里好像有一团火一样,疯狂的看文档,学技术,工作三年多,目标检测与识别、嵌入式开发、ROS机器人系统开发、物联网通讯、还有JavaScript等等太多了,对很多技术都有了解,但都并不精通,因为工作原因我没法对一项技术钻研很深,往往课题就结束了,而做课题过程中也就是刚刚好够你对该技术有个大概了解或者刚入门的水平。我一度觉得对于我这种单位来说,技术好像并不那么重要了,产生了深深的自我否定与怀疑,后来在知乎上看了一个问题,叫《那一件事让你忽然意识到打工永无出路》一定程度上解决了我的疑惑,就是不要盲目的崇拜技术,别轻易觉得自己挺重要不容易被替代。保持学习劲头可以,但要平衡好工作和生活,打工就是温饱,技术就是糊口的工具,没有多么高大上,技术可以学,不要影响生活和工作主体。这里的工作主体我觉得就是自己的文章、专利、获奖,甚至是在单位的展示度、项目的管理能力、组织协调能力等等,这些相较于技术来说还是要更重要一点,之前的我确实是不太在意这些,现在觉得这是不对的。

一个人精力有限,合理的分配自己的时间,好好生活,好好工作,才是对自己最好的交代。