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

35 篇文章 1 订阅
29 篇文章 0 订阅

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

<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;
}
// 去掉hover时显示的滚动条
:deep(.el-scrollbar__thumb) {
  display: none;
}

::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>

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个带有自动循环滚动功能的el-table表格组件。接下来,我将为您提供所需的代码片段。请注意,您需要将代码中的“YOUR_TABLE_DATA”替换为您自己的表格数据,并根据需要调整配置选项。 首先,您需要在Vue3项目中安装并引入element-ui及element-plus组件库: ``` npm install element-plus ``` 在您的Vue文件中,您需要引入以下项: ```vue <template> <el-table v-if="tableData.length" :data="tableData" :height="height" :max-height="maxHeight" :style="tableStyle" :row-style="rowStyle" @row-click="handleRowClick"> <slot></slot> </el-table> </template> <script> import { ref, watch, nextTick } from 'vue' import { ElTable } from 'element-plus' export default { name: 'MyTable', extends: ElTable, props: { autoScroll: { type: Boolean, default: true }, scrollSpeed: { type: Number, default: 20 }, scrollType: { type: String, default: 'pixel', // options: pixel, row, page validator: (value) => { return ['pixel', 'row', 'page'].indexOf(value.toLowerCase()) !== -1 } }, scrollDistance: { type: Number, default: 1 }, scrollDelay: { type: Number, default: 1000 } }, setup(props, ctx) { const scrollRef = ref(0) const scrollToIndex = (index) => { nextTick(() => { let rowHeight = ctx.slots.default()[0].children[0].clientHeight let tableBody = document.querySelector('.el-table__body-wrapper') let tableHeight = tableBody.clientHeight let tableVisibleRows = tableHeight / rowHeight let tableTotalRows = props.data.length let scrollTop = 0 if (props.scrollType === 'page') { if (index + tableVisibleRows > tableTotalRows) { scrollTop = tableTotalRows * rowHeight } else if (index > tableVisibleRows) { scrollTop = (Math.floor(index / tableVisibleRows) - 1) * tableHeight + tableVisibleRows * rowHeight } } else if (props.scrollType === 'row') { scrollTop = index * rowHeight } else { scrollTop = (index - props.scrollDistance) * rowHeight } tableBody.scrollTop = scrollTop }) } const scrollToNext = () => { let currentScroll = scrollRef.value let tableBody = document.querySelector('.el-table__body-wrapper') let tableHeight = tableBody.clientHeight let rowHeight = ctx.slots.default()[0].children[0].clientHeight let tableTotalRows = props.data.length let tableVisibleRows = tableHeight / rowHeight let maxScrollTop = (tableTotalRows - tableVisibleRows) * rowHeight let scrollDirection = currentScroll === maxScrollTop ? -1 : 1 let scrollTop = currentScroll + props.scrollDistance * rowHeight * scrollDirection scrollRef.value = scrollTop tableBody.scrollTop = scrollTop } watch(() => props.data, () => { scrollRef.value = 0 }) watch(() => props.autoScroll, () => { if (props.autoScroll) { autoScrollInterval = setInterval(() => { scrollToNext() }, props.scrollSpeed) } else if (autoScrollInterval) { clearInterval(autoScrollInterval) } }) let autoScrollInterval = null return { tableStyle: ref({}), rowStyle: ref({}), handleRowClick: (row, column, event) => { ctx.emit('row-click', row, column, event) } } }, mounted() { if (this.autoScroll) { autoScrollInterval = setInterval(() => { this.scrollToNext() }, this.scrollSpeed) } }, computed: { tableData() { return this.$props.data || [] }, height() { return `${this.$props.height}px` }, maxHeight() { return `${this.$props.maxHeight}px` } } } </script> ``` 接下来,您可以将该组件包含到您的Vue模板代码中,并根据需要配置选项: ```vue <template> <my-table :data="YOUR_TABLE_DATA" :auto-scroll="true" :scroll-speed="30" :scroll-type="'page'" :scroll-distance="1" :scroll-delay="1000"> <el-table-column prop="column1" label="Column 1"></el-table-column> <el-table-column prop="column2" label="Column 2"></el-table-column> <el-table-column prop="column3" label="Column 3"></el-table-column> <!-- You can add additional columns here --> </my-table> </template> <script> import MyTable from './MyTable' export default { components: { MyTable }, } </script> ``` 在这个例子中,组件会自动滚动到下一页,每1000ms滚动一次,以30px/秒的速度滚动, 也可以按像素或按行进行配置。请注意,您可以根据需要修改这些值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值