el-table表格还可以这么玩

343 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天第1篇,点击查看活动详情

前言

我们都知道表格是横向渲染的,一行一行去展示。不过博主这里有个需求是纵向渲染,一列一列去展示…嗯…不难...做出来了,下面是全部代码,分享出来或许能帮到你们。

案例介绍

本案例点击添加可添加一列(为后一天时间),新添加列可取消,有数据了按钮会变成保存,当添加到10条数据,自动往后推一天,永远显示10条数据

案例截图

点击添加列 可取消和保存

template模板

<template>
  <div class="app-container">
    <template>
              <el-button
              type="primary"
               v-if="isAdd"
               icon="el-icon-plus"
              size="mini"
              v-hasPermi="['manager:trader:add']"
              @click="tableAdd"
              :disabled="is10"
              >添加</el-button
            >
            <el-button
              type="primary"
              @click="dataSave"
              v-else
              size="mini"
              :disabled="nonum"
              v-hasPermi="['manager:trader:edit']"
              >{{isSave ? "保存":"取消"}}</el-button
            >
            </template>
    <el-table border  v-loading="loading" :data="tableData">
      <el-table-column label="日期" align="right">
        <el-table-column prop="name" align="center" label="汇率">
          <el-table-column
            width="100px"
            prop="tableName"
            align="center"
            label="星期"
          >
            <template slot-scope="scope">
              <div>{{ tableData[scope.$index].name }}</div>
            </template>
          </el-table-column>
        </el-table-column>
      </el-table-column>
      <el-table-column
        align="center"
        v-for="(item, index) in headerData.length"
        :key="index"
      >
        <template slot-scope="scope">
          <div v-if="islastDay(headerData[index])">
        <el-input type="number" v-model="tableData[scope.$index].data[index]" @input="updataInput(tableData[scope.$index].data[index],tableData[scope.$index].ids[index],scope.$index,index)" controls-position="right"></el-input>
          </div>
          <div v-else>{{ tableData[scope.$index].data[index]}}</div>
        </template>
        <!-- 时间区域 -->
        <template slot="header" slot-scope="{ $index }">
         {{ headerData[$index-1] }}
        </template>
      </el-table-column>
      <!-- 添加区域 -->
      <el-table-column
        align="center"
        v-for="(item, index) in tableAdds"
        :key="index + Date()"
      >
        <template slot-scope="scope" v-if="tableAdds.length > 0">
        <el-input v-model="tableAdds[0]['data'+scope.$index]" controls-position="right"></el-input>
        </template>
        <template slot="header">
          {{ newTime }}
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

script部分

export default {
  name: "trader",
  components: {},
  data() {
    return {
      width:"100%",
      height:"400px",
      is10:false,//数据是否已添加到10天后
      loading:false,
      cancel: false, //是否取消添加数据
      isAdd: true, //是否添加数据
      isSave:false,//是否保存
      loading: false, // 遮罩层
      ids: [], // 选中数组
      single: true, // 非单个禁用
      multiple: true, // 非多个禁用
      showSearch: true, // 显示搜索条件
      tableName: [],
      tableData: [{
        name:'星期一',
        data:[0.11,0.51]
      },{
        name:'星期二',
        data:[0.32,0.22]
      }], //表格数据
      headerData:['2022-08-25','2022-08-26'],//表格表头
      tableAdds: [], //添加的数据
      total: 0, // 总条数
      title: "", // 弹出层标题
      open: false, // 是否显示弹出层
      mustHitOptions: [], // 是否必中,0是  1否字典
      claimTypeOptions: [], // 领取类型字典
      prizeRewardOptions: [], // 是否有奖字典 0无奖 1有奖
      statusOptions: [], // 状态字典
      queryParams: {
        queryTime: "",
      }, // 查询参数
      newTime:undefined, // 新增的时间
      nonum:false,
      isUpdata:false,// 是否是修改操作
      upDated:{}, //修改后的数据(这里用对象可去重)
      aaa:[]
    };
  },
  watch:{
    //监听是否全部填写
    tableAdds:{
       handler(val, oldVal) {
         this.isSave = this.is0();
         if(this.isSave){
           this.isAdd = false;
         }
       },
       deep: true
    },
    //时间输入框
    'queryParams.queryTime'(val){
      if(val == ''){

      }
    }
  },
  created() {
    //this.getList();
  },
  methods: {
    //判断每列数据是否全部填写  是返回true 否则false
    is0(){
         var is0;
          const adds = this.tableAdds[0];
         if(this.tableAdds.length > 0){
           for(let i in adds){
             if(adds[i] == ''){
                is0 = false;
                break;
              }
              else{
                is0 = true;
              }
           }
         }else{
           is0 = false;
         }
          return is0;
    },
    //判断日期是否超过今天 超过返回true  不超过返回false
    islastDay(nowtime){
       var fan = false;
       var timearr = nowtime.split('-');
       var Year = new Date().getFullYear();//当前年
       var Month = new Date().getMonth() + 1;//当前月
       var Day = new Date().getDate();//当前日
       if(timearr[0] > Year || (timearr[0] == Year && timearr[1] > Month) || (timearr[1] == Month && timearr[2] > Day)){
         fan = true;
       }
       else{
         fan = false;
       }
       return fan;
    },
    //input修改事件
    //参数1:当前汇率  参数2:当前汇率对应的id
    //参数3:tableData的索引  参数4:当前汇率对应的id的索引
    updataInput(num,fromid,dataindex,idsindex){
      const arr = [];
      const tableData = this.tableData;
      const headerData = this.headerData;
      //遍历出全部数据
       for(let j=0;j<tableData.length;j++){
          for(let i=0;i<headerData.length;i++){
              arr.push({
              //'createTime':headerData[i],
              //'cardId':tableData[j].cardId,
              'id':tableData[j].ids[i],
              'moneyRate':tableData[j].data[i],
            })
          }
        }
        //遍历出修改了的数据
        for(let k=0;k<arr.length;k++){
          if(arr[k].id == fromid){
            this.upDated[fromid] = arr[k];
          }
        }

      this.isAdd = false;
      this.isSave = true;
      this.isUpdata = true;
      // if(num < -3 || num > 3){
      //   this.$message({
      //     message: '汇率配置范围-3至3',
      //     type: 'warning'
      //   });
      //   if(num < -3) this.tableData[dataindex].data[idsindex] = -3;
      //   if(num > 3) this.tableData[dataindex].data[idsindex] = 3;
      //    }
      if(num === '' || num === undefined || num === null){
         this.$message({
            message: '请配置汇率',
            type: 'warning'
          });
         this.nonum = true;
      }
      else{
         this.nonum = false;
      }
    },
    //保存或取消
    dataSave(){
      if(this.isSave){
        this.addFn();
      }
      else{
         this.tableAdds = [];
         this.isAdd = true;
      }
    },
    //保存数据
    addFn() {
       if(this.isUpdata){//是修改
       const data = [];
       const xindata = {};
        const xin2data = [];
       const upDated = this.upDated;
       //对象转数组
       for(let item in upDated){
           data.push(upDated[item]);
       }
        updateTrader(data).then(response=>{
          if(response.code == 200){
            this.$message.success("修改成功");
            this.isAdd = true;
            this.getList();
          }
        })
       }
       else{//是新增
          const arr = [];
          const adds = this.tableAdds[0];
          const tableData = this.tableData;
          for(let i in adds){
              arr.push({
                moneyRate:adds[i]
              })
          }
          for(let j=0;j<tableData.length;j++){
            arr[j].cardId = tableData[j].cardId
          }
          const data={
            createTime:this.newTime,
            tabData:arr
          }
          addTrader(data).then(response=>{
            if(response.code == 200){
              this.$message.success("添加成功");
              this.isAdd = true;
              this.tableAdds = [];
              this.getList();
            }
          })
       }
    },
    // 添加操作
    tableAdd() {
        this.isAdd = false;
        //获取到表格最后一个时间加一天
        let endtime = this.headerData.length == 0 ? this.formatDay(new Date().getTime()) : this.headerData[this.headerData.length-1];
        this.newTime = this.formatDay(new Date(endtime).getTime() + 3600 * 1000 * 24);

         //确保10条数据(数据大于10条,删除首条)
        const tableData = this.tableData;
        let datalength = this.headerData.length;
          if(datalength >= 10){
            for(let i =0;i<tableData.length;i++){
              tableData[i].data.splice(0,1);
            }
          this.headerData.splice(0,1);
          }
        const add ={};
        for(var i =0;i<tableData.length;i++){
          add['data'+i] = '';
        }
        this.tableAdds.push(add);
    },
    /**
     * 日期格式化
     */
    formatDay(cellValue) {
      if (cellValue == null || cellValue == "") return "";
      var date = new Date(cellValue);
      var year = date.getFullYear();
      var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
      var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
      return year + '-' + month + '-' + day;
    }
  },
};

返回表头的长度对应数据的长度,这是关键,否则表格不成立

必须要后端配合返回相应的数据结构哦

      tableData: [{
        name:'星期一',
        data:[0.11,0.51]
      },{
        name:'星期二',
        data:[0.32,0.22]
      }], //表格数据
      headerData:['2022-08-25','2022-08-26'],//表格表头

css

<style lang="scss" scoped>
// 给表头加斜线的css
::v-deep .el-table th {
  overflow: initial;
}
::v-deep .el-table .el-table__header-wrapper th {
  height: 30px !important;
}
::v-deep .el-table--medium th {
  padding: 0 !important;
}
::v-deep .el-table thead tr:first-of-type th:first-of-type,
::v-deep .el-table thead tr:nth-of-type(2) th:first-of-type {
  border-bottom: none;
}
::v-deep .el-table thead tr:first-of-type th:first-of-type .cell {
  text-align: right;
}
::v-deep .el-table thead tr:nth-of-type(2) th:first-of-type .cell {
  padding-left: 0;
  position: absolute;
  top: 12px;
  left: 16px;
  z-index: 99;
}
::v-deep .el-table thead tr:last-of-type th:first-of-type .cell {
  text-align: left;
}
::v-deep .el-table thead tr:first-of-type th:first-of-type:before,
::v-deep .el-table thead tr:last-of-type th:first-of-type:before {
  content: "";
  position: absolute;
  width: 1px;
  background-color: #dfe6ec;
  display: block;
}
::v-deep .el-table thead tr:first-of-type th:first-of-type:before {
  height: 198px; //根据情况调整
  top: 0;
  left: 0; //根据情况调整
  transform: rotate(-32deg); //根据情况调整
  transform-origin: top;
  z-index: 2;
}
::v-deep .el-table thead tr:last-of-type th:first-of-type:before {
  height: 112px; //根据情况调整
  top: -60px;
  left: 0; //根据情况调整
  transform: rotate(-62deg); //根据情况调整
  transform-origin: top;
  z-index: 2;
}
::v-deep .el-input{
  width: 90%;
  .el-input__decrease,.el-input__increase{
    background: #FFFFFF;
  }
}
</style>

当我们需要覆盖element-ui中的样式时只能通过深度作用选择器,即::v-deep,也叫样式穿透

总结

不论遇到一些多棘手的需要,首先要先静下心去思考,其次多看文档,利用文档里的方法或一些参数,相互结合去寻求解决的办法,举一反三,多尝试。