Element 表格实现左右自动滚屏

11 篇文章 0 订阅
3 篇文章 0 订阅

前两天公司需要实现一个功能(用于大屏幕投屏):

自定义表头及内容 ,并且固定左边几列实现: 从左往右滚屏 滚动到后面没有列后 开始第二页的滚屏,以此类推 拉取到最后 没有数据又从第一页开始滚

实现思路:

  1. 监听滚动事件,
  2. 页面一加载去后台调用数据,成功后触发事件
  3. 判断是否滚动到最后 如果滚到最后  将scrollLeft 设置为0,没有就scrollLeft++;

div左边卷去的长度=div的总宽 -  div屏幕可视区域的宽(div 即 设置overflow 的div )

上面的列子即为 scrollLeft=scroollWidth-clientWidth;

前后端商量 给什么样的数据结构 宽度,固定多少列,都有后台控制  如下:

 

后台分表头和数据 这样给 TableTitle + TableData  这样的结构 ;

 

具体代码如下:

<template>
<article class="schedule">
  <header>
    <h1>{{tilte}}</h1>
  </header>
  <article>
    <template>
      <el-table
        ref="productionSchedle"
        :data="tableData"
        height="calc(100vh - 116px)"
      >
        <template
          v-for="(item,index) in tableTitle">
          <el-table-column
            :width="item.width"
            :prop="item.prop"
            :label="item.title"
            :fixed="item.fixed==='left'"
            :render-header="renderHeader">
            <template slot-scope="scope">
              <span>{{scope.row[item.prop]}}</span>
            </template>
          </el-table-column>
        </template>
      </el-table>
    </template>
  </article>
</article>
</template>
<script>
    export default {
     name: "productionSchedule",
      data() {
        return {
          tilte:'生产计划进度表',
          tableTitle:[],
          tableData:[],
          page:1,
          pageSize:0,
          refreshTime:3000,
          timer_code:'',
          count:0,  //计数
        }
      },
      created(){
      },
      mounted(){
        window.addEventListener('scroll', this.handleScroll,true);
        this.getData();
      },
      watch: {},
      methods: {
        handleScroll(){
            //重点代码
          if(this.$refs.productionSchedle!=undefined){
           // console.log(this.$refs);
            let scollwidth=this.$refs.productionSchedle.$el.childNodes[2].scrollWidth;
            let scrollLeft=this.$refs.productionSchedle.$el.childNodes[2].scrollLeft;
            let clientWidth=this.$refs.productionSchedle.$el.childNodes[2].clientWidth;
            let num=scollwidth-clientWidth;
            if(parseInt(scrollLeft) == num){
              if(this.count==0){       //此处是为了防止scrollLeft 会出现约等于的值 如果不判断会进来很多次,就会调很多次接口,并且 page 可能+多次 就看不到 一页一页的效果
                this.count++;
                this.getData().then(()=>{
                    this.count=0; //成功后修改状态
                    console.log("成功");
                }).catch((error)=>{
                  console.log("异常错误"+error);
                });
              };
            }else{
                //实现滚动的代码
              this.$refs.productionSchedle.$refs.bodyWrapper.scrollLeft++;
            };

          }
        },
        getData(){
          let _param={page:this.page,pagesize:this.pageSize};
          return new Promise((resolve, reject) => {
            this.$axios({
              method: 'post',
              url:'http://接口域名/reportapi/YisJyReportOperation/SelProducePlanSpeedReportData',
              headers: { token: localStorage.getItem('yis_pc_token') },
              data: _param
            }).then(response => {
              if (response.data.errcode=="1000") {
                console.log(response.data);
                this.tilte=unescape(response.data.retdata[0].MainTitle[0].Title);
                this.pageSize=unescape(response.data.retdata[0].MainTitle[0].Size);
                this.refreshTime=(unescape(response.data.retdata[0].MainTitle[0].RefreshTime)*1000);
                if(JSON.stringify(response.data.retdata[0].TableTitle)=="[{}]"){
                  return false
                }
                let tableTitle=response.data.retdata[0].TableTitle;
                tableTitle.forEach((item,index)=>{
                    item.prop=unescape(item.prop);    //后台乱码传的 >>>解码 
                    item.title=unescape(item.title);
                    item.fixed=unescape(item.fixed);
                    item.width=unescape(item.width);
                });
                this.tableTitle=tableTitle;
                if(JSON.stringify(response.data.retdata[0].TableData)=="[{}]"){
                  console.log("无数据~");
                  this.page=1;
                  this.pageSize=0;
                  this.getData();
                }else{
                  this.page++;
                  let tableData=response.data.retdata[0].TableData;
                  tableData.forEach((item,index)=>{
                    for(let i in item){
                      item[i]=unescape(item[i])
                    };
                  });
                  this.tableData=tableData;
                  console.log("触发滚动事件")
                  //需要把当前的触发事件放在成功后并且有数据返回,无数据时调用接口
                  setTimeout(()=>{
                    this.$refs.productionSchedle.$refs.bodyWrapper.scrollLeft=1; //触发滚动事件
                  },3000);
                };
                resolve(response);
              }else {
                window.removeEventListener('scroll', this.handleScroll); //移除监听事件
                this.showToast("info",response.data.errmsg);
                resolve(response.data.errmsg)
              };
            },(error) => {
              //如果错误移除监听事件
              window.removeEventListener('scroll', this.handleScroll);
              this.showToast("error",error);
              reject(error);
            });
          })
        },
        showToast(type, msg) {
          if (type == "success") {
            this.$notification({
              message: msg,
              type: "success"
            });
          } else if (type == "error") {
            this.$notification({
              message: msg,
              type: "error"
            });
          } else if (type == "info") {
            this.$notification({
              message: msg,
              type: "warning"
            });
          }
        },
        // render 事件
        renderHeader(h,{column}) { // h即为cerateElement的简写,具体可看vue官方文档
          return h(
          'span',
            {domProps: {
                innerHTML: `${column.label}`
              },},
            [],);
        },
      },
      destroyed(){
       console.log("销毁");
        window.removeEventListener('scroll', this.handleScroll);
      },

    }
</script>

<style scoped lang="less">
  @yellow:#ff5402;
.schedule{
  background-color: #000000;
  height: 99.5vh;
  padding-top: 0.1px;
  header{
    background-color:@yellow;
    height: 80px;
    margin-bottom: 15px;
    border-radius: 40px;
    text-indent: 30px;
    h1{
      text-align: left;
      line-height: 80px;
      /*font-size: 2.5rem;*/
      font-size: 4rem;
      margin-top: 15px;
    }
  }
  article{
    height: auto;
  }
  article::-webkit-scrollbar {
      width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
      height: 10px;
    }
  article::-webkit-scrollbar-thumb {
    border-radius: 5px;
    background: #7d7b7c;
  }
  article::-webkit-scrollbar-track {
    border-radius: 0;
    background: #979596;
  }

}
</style>
<style lang="less">
  .schedule{
    @import "~@/components/reportCommon/theme.less";
    /*  .el-table__body{
          width: auto!important;
          min-width: 100% !important;
       }
      .el-table__header{
        width: auto!important;
        min-width: 100% !important;
      }*/
    .el-table{
      color: #ffffff;
      &::before{
        height: 0px;
      }
      th,tr {
        background-color: rgb(101,99,100);
      }
      th.is-leaf {
        border-bottom: 1px dashed #ff5402;
        text-align: center;
      }
      .cell {
      /*  font-size: 1.5rem !important;*/
        span{
          font-size: 2.2rem !important;
        }
        //line-height: 28px;
      }
    }
    .el-table__body-wrapper{
      background-color: #656365;
    }

    /deep/ .el-table__body tr.hover-row > td{
      background: none;
    }
   /deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
        background: none;
      }
    .el-table__fixed::before{
      height: 0px;
    }
    .el-table__fixed{
      &:nth-last-of-type(1){
        margin-top: 83px !important;
      }
    }
      .el-table td, .el-table th.is-leaf {
        border-bottom: 1px dashed #ff5402;
        text-align: center;
      /*  font-size: 1.5rem;*/
      }
      .el-table thead {
        color: #ff5402;
        font-weight: 500;
      }
      .el-table__header {
        span{
       /*   font-size: 1.5rem;*/
          font-size:2.5rem;
        }
      }
      .el-table__empty-block {
        background-color: #656364 ;
      }
    .el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar {/*滚动条整体样式*/
      .el-table-scrollbar;
    }
    .el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
      .el-table-scrollbar-thumb_gary;
    }
    .el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-track {/*滚动条里面轨道*/
      .el-table-scrollbar-track_gary;
    }
    .el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar {/*滚动条整体样式*/
      .el-table-scrollbar;
    }
    .el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
      .el-table-scrollbar-thumb_gary;
    }
    .el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-track {/*滚动条里面轨道*/
      .el-table-scrollbar-track_gary;
    }

  }
</style>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值