el-table表格自动循环向上滚动鼠标放上去停止,移开恢复

排序的图标是两个图片,点击向后端发请求带不同的参数

javascript 复制代码
<template>
    <div style="height: 100%" class="table-content">
      <div :style="{ 'position': 'absolute', 'z-index': '9999', 'right': '3%', 'top': 0 }"
        :class="`tagBtn bg${centerKey}`">
        <div class="item" @click="centerKey = 1"></div>
        <div class="item" @click="centerKey = 2"></div>
      </div>
      <div style=" flex:1;height:0px" class="table-info" id="table">
        <el-table class="temp-table" ref="tableRef" @current-change="currChange" highlight-current-row
          :row-class-name="tableRowClassName" :data="tableData" size="mini" height="100%" :key="rank"
          @cell-mouse-enter="handleMouseOver" @cell-mouse-leave="handleMouseLeave">
          <el-table-column prop="rank" label="排名" align="center" min-width="80" show-overflow-tooltip>
            <template #header>
              <div style="display: flex;flex-direction: row;align-items: center;justify-content: center;"
                @click="sortChange">
                <span>排名</span>
                <span style="cursor: pointer;" v-if="show"><img
                    src="../../../assets/imgs/jiangxu.png" /></span>
                <span style="cursor: pointer;" v-if="!show"><img
                    src="../../../assets/imgs/shengxu.png" /></span>
              </div>
            </template>
            <template #default="scope">
              <span>{{ scope.row.rank }}</span>
            </template>
          </el-table-column>
          <el-table-column label="xx" prop="COMMUNITYNAME" min-width="120" align="left" show-overflow-tooltip>
          </el-table-column>
          <el-table-column label="xxx" prop="AVGTEMP" min-width="85" align="center" show-overflow-tooltip>
          </el-table-column>
          <el-table-column v-if="centerKey === 1" label="xxx" prop="LOWTEMP" min-width="120" align="center"
            show-overflow-tooltip>
          </el-table-column>
          <el-table-column v-else label="xxx" prop="OVERTEMP" min-width="120" align="center" show-overflow-tooltip>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </Card>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs, watch, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useAppStore } from '@/store/modules/app'
import { listRoomTempRange } from '@/api/Tou/index.ts'


export default defineComponent({
  components: {
  },
  props: {
    intervalTime: {
      type: Number,
      default: 20
    }
  },
  setup(props) {
    // store
    const appStore = useAppStore()
    const router = useRouter()

    const state = reactive({
      tableRef: null,
      tableData: [],
      centerKey: 1,
      type: 0,
      timer: null,
      distance: 0,
      mouserEnter: false, //用来标识鼠标是否在表格区域(防止请求接口之后,鼠标还指示在图表上)
      mouseScroll: false,
      currdata: null,
      show: true,
    }) as any

    const methods = {
      sortChange() {
        state.show = !state.show
        if (state.show === true) {
          state.type = 0 // 0降序
          methods.getData(state.type);
        } else {
          state.type = 1 // 1升序
          methods.getData(state.type);
        }
      },
      getData(type: number) {
        let params = {
          temporder: type == 0 ? 0 : 1, // 1升序 0降序
        }
        listRoomTempRange(params)
          .then(res => {
            // 处理成功的响应
            // 返回的数据顺序是后端处理好的,这里只需要按顺序添加编号即可            
            const data = res?.data.map((item: any, index: number) => {
              return {
                ...item,
                rank: index + 1,
              }
            })
            methods.initData(data);
          })
          .catch(error => {
            // 处理错误的响应
            console.error(error);
          });
      },
        
      // 设置行颜色
      tableRowClassName({ row, rowIndex }) {
        if (rowIndex % 2 == 0) {
          return "warning-row";
        } else if (rowIndex % 2 == 1) {
          return "success-row";
        }
        return "";
      },

      // 切换选项抛出事件
      currChange(val, i) {
        state.currdata = val;
      },

      initData(data) {
        //根据行数判断表格是否溢出,溢出滚动,否则不滚动
        if (data.length > 9) {

          state.tableData = [...data, ...data];
        } else {
          state.tableData = data;
        }
        //如果当前有选中的话,则请求接口之后高亮此项
        if (state.currdata) {
          let index = state.tableData.filter((r) => {
            if (r.COMMUNITYID == state.currdata.COMMUNITYID) {
              return r;
            }
          });
          state.tableRef.setCurrentRow(index[0]);
        } else {
          // 初始时是默认选中第一条
          state.tableRef.setCurrentRow(state.tableData[0]);
        }
        nextTick(() => {
          state.tableRef && state.tableRef.doLayout(); //解决表格错位
          if (data.length > 9 && !state.mouserEnter) {
            methods.scroll();
            methods.mouseWheel();
          }
        });
      },

      // 无缝滚动
      scroll() {
        window.clearInterval(state.timer);
        state.mouserEnter = true;
        const tableEl = document.getElementById('table')
        const bodyContent = tableEl.getElementsByClassName('el-table__body')[0];
        const bodyWrapperHeight = tableEl.getElementsByClassName('el-table__body-wrapper')[0].clientHeight;
        const bodyContentHeight = tableEl.getElementsByClassName('el-table__body')[0].clientHeight;
        if (bodyWrapperHeight < bodyContentHeight) {
          state.timer = setInterval(() => {
            state.distance -= 1;
            bodyContent.style.top = `${state.distance % bodyContent.offsetHeight / 2}px`;
          }, 20);
        }
      },
      // 滚轮滚动
      mouseWheel() {
        state.mouserEnter = true;
        const tableEl = document.getElementById('table')
        const bodyWrapper = tableEl.getElementsByClassName('el-table__body-wrapper')[0];
        const bodyContent = tableEl.getElementsByClassName('el-table__body')[0];
        bodyWrapper.addEventListener('mousewheel', (e) => {
          // 滚动table的时候,禁止屏幕滚动
          e.preventDefault();
          state.distance -= e.deltaY / 2;
          if (state.distance > 0) {
            state.distance = 0;
          }
          if (bodyContent.offsetHeight > bodyWrapper.offsetHeight) {
            bodyContent.style.top = `${state.distance % bodyContent.offsetHeight / 2}px`;
          }
        }, { passive: false })
      },
      // 鼠标移入停止滚动
      handleMouseOver() {
        window.clearInterval(state.timer);
        state.mouserEnter = true;
      },
      // 鼠标移出,恢复滚动
      handleMouseLeave() {
        methods.scroll();
      },
    }

    const timer2 = ref(null)

    onMounted(() => {
      methods.getData(0)
      timer2.value = setInterval(() => {
        methods.getData(state.type)
      }, 1000 * props.intervalTime);
    })

    onUnmounted(() => {
      clearInterval(timer2.value);
    })

    return {
      ...toRefs(state),
      ...methods,
    }
  }
})
</script>

<style lang="less" scoped>
.card-info {
  position: relative;
}

.table-content {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 3%;

  .table-info {
    height: 0;
    flex: 1;
    border-radius: 6px;
    overflow: hidden;
  }

  .tagBtn {
    width: 129px;
    height: 23px;
    background: url(../../../assets/imgs/upToPar1.png) no-repeat;
    background-size: 100% 100%;
    display: flex;
    flex-direction: row;
    justify-content: center;

    &.bg2 {
      background: url(../../../assets/imgs/upToPar2.png) no-repeat;
      background-size: 100% 100%;
    }

    &>.item {
      width: 65px;
      cursor: pointer;

      &:last-child {
        margin-left: 4px;

      }
    }
  }
}

.el-table {
  border-radius: 6px;
}

:deep(.el-table td.el-table__cell div) {
  padding-left: 8px !important;
  padding-right: 8px !important;
  font-size: 12px;
  font-family: MicrosoftYaHei;
  color: #C0D7FB;
  line-height: 16px;
}

:deep(.el-table th>.cell) {
  text-align: center;
}

::v-deep .el-table .warning-row {
  height: 36px;
  background: #070C33;
  // background: linear-gradient(90deg, rgba(0, 15, 35, 0) 0%, #000E23 100%);
}

::v-deep .el-table .success-row {
  height: 36px;
  background: #0A1749;
  // background: rgba(20, 57, 140, 0.34);
}

::v-deep .el-table .current-row {
  height: 36px;
  background: #043A90;
}

::v-deep .el-table--scrollable-y .el-table__body-wrapper {
  overflow: hidden;
}

::v-deep .el-table__body {
  position: relative;
  min-height: 100%;
  width: 100%;
}

// 表头样式
.el-table .el-table__header th {
  background: rgba(26, 131, 255, 0.29);
}

:deep(.el-table__header) {
  height: 46px !important;
}

:deep(.el-table thead th.el-table__cell ) {
  color: #FFFFFF !important;
  font-size: 14px !important;
}

::v-deep .el-table_3_column_11 .is-left .is-leaf {
  border-radius: 6px 0px 0px 6px;
}

:deep(.el-table__body tr.current-row>td) {
  color: #FFFFFF !important;
  background-color: #0073FF !important;
}
</style>
相关推荐
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
不是鱼5 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js
开心工作室_kaic6 小时前
springboot476基于vue篮球联盟管理系统(论文+源码)_kaic
前端·javascript·vue.js
川石教育6 小时前
Vue前端开发-缓存优化
前端·javascript·vue.js·缓存·前端框架·vue·数据缓存
搏博6 小时前
使用Vue创建前后端分离项目的过程(前端部分)
前端·javascript·vue.js
isSamle6 小时前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django
ss2737 小时前
基于Springboot + vue实现的汽车资讯网站
vue.js·spring boot·后端
武昌库里写JAVA7 小时前
浅谈怎样系统的准备前端面试
数据结构·vue.js·spring boot·算法·课程设计
TttHhhYy8 小时前
uniapp+vue开发app,蓝牙连接,蓝牙接收文件保存到手机特定文件夹,从手机特定目录(可自定义),读取文件内容,这篇首先说如何读取,手机目录如何寻找
开发语言·前端·javascript·vue.js·uni-app