记Vue elementUi table进行数据统计开发

需求:如下图所示(数据为模拟数据)
概念图
概念图
因为公共部分有很多,所以直接做一个公共的table组件

  1. table组件代码
<template>
  <div id="elTable">
    <el-table
      :data="propsData.list"
      border
      :cell-class-name="cellName"
      :header-cell-style="headCell"
      v-if="propsData.list.length > 0"
    >
      <el-table-column
        property="name"
        align="center"
        label="门店名称"
        width="120"
        fixed
        v-if="propsData.type == 'storeCarStock'"
      >
        <template slot-scope="scope">
          {{ scope.row.name }}
        </template>
      </el-table-column>
      <el-table-column align="center" width="120px" fixed>
        <template slot="header">
          <div class="rowHeader">
            <div>
              <span class="span1">{{ propsData.slotCloName }}</span>
              <span class="span2">日期</span>
            </div>
            <div class="line"></div>
          </div>
        </template>
        <template slot-scope="scope">
          {{ scope.row.companyname }}
        </template>
      </el-table-column>
      <el-table-column
        :label="item"
        :prop="item"
        v-for="(item, index) in propsData.headerData"
        :key="index"
        align="center"
      >
        <template slot="header">
          <p>{{ item.split("/")[0] }}</p>
          <p>{{ item.split("/")[1] }}</p>
        </template>
        <template slot-scope="scope">
          <el-popover
            placement="top-start"
            title="标题"
            width="200"
            trigger="hover"
            content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"
            v-if="scope.$index == 0"
          >
            <div
              slot="reference"
              :class="
                scope.row[item] % 2 == 0 ? 'warning totalRow' : 'totalRow'
              "
            >
              {{ scope.row[item] }}
            </div>
          </el-popover>
          <div v-else>
            {{ scope.row[item] }}
          </div>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination">
      <el-pagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        :total="propsData.pager.total"
        @current-change="pageChange"
        @size-change="sizeChange"
        :page-sizes="[10, 30, 50]"
        :page-size="10"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
export default {
  props: ["propsData"],
  name: "TableComp",
  data() {
    return {
      headCell: {
        background: "rgb(246, 248, 249)",
        color: "#858796",
        fontWeight: "normal",
      },
    };
  },

  methods: {
    cellName(row) {
      if (row.rowIndex == 0) {
        return "rowIndxStyle";
      } else {
        return "";
      }
    },
    pageChange(val) {
      this.$emit("pageChange", val);
    },
    sizeChange(val) {
      this.$emit("sizeChange", val);
    },
  },
};
</script>

<style lang="scss">
#elTable {
  .el-el-table__row {
    padding: 0;
  }
  .el-table--mini,
  .el-table--small,
  .el-table__expand-icon {
    font-size: 14px;
  }
  .headClass {
    background: #ddd;
  }
  .rowIndxStyle {
    padding: 0;
    .cell {
      padding: 0;
      border-radius: 0;
    }
  }
  .warning {
    background: #e6a23c;
    color: #fff;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .totalRow {
    font-size: 14px;
    height: 40px;
    line-height: 40px;
  }
  .rowHeader {
    position: relative;
    width: 120px;
    left: -10px;
    .line {
      position: absolute;
      width: 1px;
      height: 132px;
      background: #eaecf4;
      top: -38px;
      left: 58px;
      transform: rotate(-65deg);
    }
    div {
      height: 56px;
      .span1 {
        position: relative;
        top: 30px;
        left: -10px;
      }
      .span2 {
        position: relative;
        top: 6px;
        left: 8px;
      }
    }
  }
  .el-table th,
  .el-table tr {
    padding: 0 !important;
  }
  .pagination {
    margin: 20px 0;
    padding: 20px 0;
    text-align: center;
  }
}
</style>

2.父组件代码

<template>
  <div
    class="storestock"
    v-loading="loading"
    :element-loading-text="loadingText"
  >
    <TableComp
      :propsData="{
        list,
        pager,
        headerData,
        slotCloName: '企业',
        type: 'storeCarStock',
      }"
      @pageChange="pageChange"
      @sizeChange="sizeChange"
    ></TableComp>
  </div>
</template>

<script>

import TableComp from "./TableComp";
import { mockData } from "./mock";
export default {
  components: { TableComp },
  data() {
    return {
      // 传递到子组件的数据
      list: [],
      pager: {},
      headerData: [],
      loadingText: "数据查询中,请耐心等待...",
      loading: false,
      dialogVisible: false,
    };
  },

  created() {
    this.getList();
  },

  methods: {
    getList() {
      this.loading = true;
      let _this = this;
      let search = this.search;
      setTimeout(function() {
        _this.loadingText = "数据加载成功" + new Date().toLocaleTimeString();
        let day = _this.search.day ? _this.search.day : 7;
        const { arr, brr } = mockData(day, "store");
        _this.headerData = arr;
        _this.list = brr;
        _this.pager = {
          limit: search.limit,
          skip: search.skip,
          total: 20,
        };
      }, 2000);
      setTimeout(function() {
        _this.loading = false;
        _this.loadingText = "数据查询中,请耐心等待...";
      }, 3000);
    },
   
    pageChange(val) {
      console.log(val);
    },
    sizeChange(val) {
      console.log(`${val}`);
    },
  },
};
</script>
  1. 模拟数据方法的代码
function mockData(dayNum, type) {
  let day = dayNum ? dayNum : 7;
  let arr = getDay(day);
  let brr = [];

  for (let i in arr) {
    let obj = {
      name: "门店名称" + i,
      companyname: `${type == "city" ? "城市名称" : "企业名称"}` + i,
    };
    for (let k in arr) {
      obj[arr[k]] = Math.random().toFixed(2);
    }
    brr.push(obj);
  }
  let total = {
    name: "总计",
    companyname: `${type == "city" ? "总计" : ""}`,
  };
  for (let j in arr) {
    total[arr[j]] = parseInt((Math.random() * 100).toFixed(2));
  }
  brr.unshift(total);

  return { arr, brr };
}
function getDay(day) {
  var myDate = new Date();
  myDate.setDate(myDate.getDate());
  var dateArray = [];
  var dateTemp;
  var flag = 1;
  for (var i = 0; i < day; i++) {
    dateTemp = myDate.getMonth() + 1 + "-" + myDate.getDate() + "/";
    let ymdStr = `${myDate.getFullYear()}-${myDate.getMonth() +
      1}-${myDate.getDate()}`;

    dateTemp += getweekday(ymdStr);
    if (isToday(ymdStr)) {
      dateTemp += "(今日)";
    }
    dateArray.push(dateTemp);
    myDate.setDate(myDate.getDate() - flag);
  }
  return dateArray;
}
function isToday(date) {
  return new Date().toDateString() === new Date(date).toDateString();
}
function getweekday(date) {
  var weekArray = new Array(
    "周日",
    "周一",
    "周二",
    "周三",
    "周四",
    "周五",
    "周六"
  );
  var week = weekArray[new Date(date).getDay()];
  return week;
}

export { mockData };

目录结构在这里插入图片描述
注意的点:

  1. element UI table 自定义头部,官网可查。
  2. 分隔头部和日期的样式(自定义头部 + css处理)
  3. 处理总计的时候,因为还要对总计里的数据做处理,所以官网的总计处理方法不适用,只能添加了一行数据,放在数据第一位,模拟总计,通过slot 单独处理
//模拟总计
let total = {
    name: "总计",
    companyname: `${type == "city" ? "总计" : ""}`,
  };
  for (let j in arr) {
    total[arr[j]] = parseInt((Math.random() * 100).toFixed(2));
  }
  brr.unshift(total);
  //处理
  <template slot-scope="scope">
    <el-popover
        placement="top-start"
        title="标题"
        width="200"
        trigger="hover"
        content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"
        v-if="scope.$index == 0"
      >
        <div
          slot="reference"
          :class="
            scope.row[item] % 2 == 0 ? 'warning totalRow' : 'totalRow'
          "
        >
          {{ scope.row[item] }}
        </div>
      </el-popover>
      <div v-else>
        {{ scope.row[item] }}
      </div>
  </template>

4.表头分行展示的处理
在这里插入图片描述

// elementUI 官网  自定义头部 有详细说明
  <template slot="header">
       <p>{{ item.split("/")[0] }}</p>
       <p>{{ item.split("/")[1] }}</p>
  </template>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue ElementUI是一套基于Vue.js 2.0的桌面端组件库,偏重于后台应用场景,其中Table是其中一个常用的组件。在使用Table组件时,经常会遇到数据较多,渲染速度变慢的问题,此时可以使用数据懒加载来优化用户体验。 数据懒加载顾名思义,就是在页面滚动或者点击“加载更多”的时候,动态加载数据,达到优化渲染速度的效果。在使用Vue ElementUITable组件时,可以通过以下步骤实现数据懒加载: 1. 在Table组件中增加一些属性,包括当前页码、每页显示数量以及总数据量等。 2. 定义一个方法,用于获取数据。该方法需要根据传递的参数(包括当前页码和每页显示数量)向后端发起请求,并将返回的数据填充到Table组件中。 3. 在Table组件的配置项中,将分页组件的位置配置为“none”,并设置“load-once”属性为false,这样每次数据加载完成后,依然会保留分页组件和过滤器等配置信息。 4. 使用Vue的钩子函数mounted,实现页面初始化时加载第一页数据的功能。 5. 通过监听Table组件的“load”事件,在用户滚动页面或者点击“加载更多”时,动态调用获取数据的方法,加载下一页数据。 通过以上实现数据懒加载的步骤,可以有效减少页面初次加载的时间,提高用户体验。同时,需要注意的是在获取数据时要合理控制每次请求的数据量,避免过多的网络请求导致性能下降。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web_Hsir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值