vue3实现多表头列表el-table,拖拽,鼠标滑轮滚动条优化

🚀 个人简介:某大型测绘遥感企业资深Webgis开发工程师,软件设计师(中级)、优快云优质创作者
💟 作 者:柳晓黑胡椒❣️
📝 专 栏:vue实践
🌈 若有帮助,还请关注点赞收藏,不行的话我再努努力💪💪💪

需求背景

需要实现多表头列表的用户体验优化

解决效果

index.vue

<!--/**
* @author: liuk
* @date: 2024-07-03
* @describe:**** 多表头列表
*/-->
<template>
  <el-table ref="tableRef" height="calc(100% - 80px)" :data="listData" border v-loading="loading" stripe
            style="width: 100%" :resizable="false" @mousedown="mouseDownHandler" @mouseup="mouseUpHandler"
            @mousemove="mouseMoveHandler" element-loading-text="数据加载中...">
    <el-table-column label='时间' prop="tiem" width="145" fixed align="center" v-if="listData.length">
      <template #default="scope">
        {{ moment(scope.row['time']).format('YYYY/MM/DD HH:mm') }}
      </template>
    </el-table-column>
    <el-table-column v-for="(item, index) in keyArr" :key="index" :label=item.name :prop=item.props
                     align="center" :width="item.name.length * 12 + 20 > 110 ? item.name.length * 12 + 20 : 110">
      <template #default="scope">
        <el-input class="cell-input" @change="addEditItem(scope.row[item.props])" :disabled="!disadledFalg"
                  v-model.number="scope.row[item.props].rainstormValue"/>
      </template>
    </el-table-column>
  </el-table>
</template>

<script lang="ts" setup>
import {reactive, toRefs} from "vue"
import moment from "moment";

const model = reactive({
  keyArr: [...] // {name: '名称', props: 'name'}
  listData: [],
  loading: false,
})
const { keyArr,listData,loading} = toRefs(model)

onMounted(() => {
  addTableWheel()
})

// 列表长表头拖拽优化
const tableRef = ref(null)
const mouseFlag = ref(false)
const mouseOffset = ref(0)
const addTableWheel = () => {
  tableRef.value.scrollBarRef.wrapRef.addEventListener('wheel', event => {
    event.preventDefault()
    const delta = event.deltaX || event.deltaY
    tableRef.value.scrollBarRef.wrapRef.scrollLeft += delta
  })
}
const mouseDownHandler = (e) => {
  mouseOffset.value = e.clientX;
  mouseFlag.value = true;
}
const mouseUpHandler = () => {
  mouseFlag.value = false;
}
const mouseMoveHandler = (e) => {
  let divData = tableRef.value.scrollBarRef.wrapRef;
  if (mouseFlag.value) {
    divData.scrollLeft -= (-mouseOffset.value + (mouseOffset.value = e.clientX));
  }
}
</script>

<style lang="scss" scoped>
:deep(.el-table) {
  .el-table__inner-wrapper {
 	height: 100% !important;
  }
  .el-scrollbar__thumb {
    background: #151515;
  }
}
</style>
### 解决方案 在使用 `el-table` 时,如果固定表头和左侧第一列后,拖动滚动条时表头不动的问题,可以通过监听滚动事件并动态调整表头的样式来解决。以下是具体的解决方案: #### CSS 样式调整 首先需要确保固定的表头和左侧第一列的高度与整个表格保持一致,并且消除可能影响滚动为的伪元素。可以参考以下样式: ```css /* 确保固定列高度与表格一致 */ .el-table__fixed, .el-table__fixed-right { height: calc(100% - 33px) !important; /* 根据实际情况调整高度 */ } /* 去掉固定列下方的横线 */ .el-table__fixed::before, .el-table__fixed-right::before { background: transparent !important; display: none; } /* 调整滚动条底部空隙 */ .el-table__fixed-body-wrapper .el-table__body { padding-bottom: 20px; /* 根据滚动条高度调整 */ } ``` #### JavaScript 动态调整表头位置 为了确保表头在横向滚动时能够同步移动,可以通过监听滚动条的 `scrollLeft` 属性,并将该值应用到表头的 `marginLeft` 样式上。 ```javascript // 获取表格和滚动容器的 DOM 元素 const table = document.querySelector(&#39;.el-table&#39;); const scrollBar = table.querySelector(&#39;.el-scrollbar__wrap&#39;); // 监听滚动事件 scrollBar.addEventListener(&#39;scroll&#39;, () => { const scrollLeft = scrollBar.scrollLeft; // 获取横向滚动距离 const header = table.querySelector(&#39;.el-table__header&#39;); // 获取表头 DOM 元素 // 动态调整表头的 marginLeft header.style.marginLeft = `-${scrollLeft}px`; }); ``` #### Vue 组件实现示例 如果使用 Vue 框架,可以通过 `ref` 和生命周期方法实现上述逻辑: ```vue <template> <el-table ref="table" :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="150" fixed /> <el-table-column prop="name" label="姓名" width="120" /> <el-table-column prop="address" label="地址" /> </el-table> </template> <script> export default { data() { return { tableData: [ { date: &#39;2023-10-01&#39;, name: &#39;张三&#39;, address: &#39;北京市&#39; }, { date: &#39;2023-10-02&#39;, name: &#39;李四&#39;, address: &#39;上海市&#39; }, { date: &#39;2023-10-03&#39;, name: &#39;王五&#39;, address: &#39;广州市&#39; }, ], }; }, mounted() { this.$nextTick(() => { const scrollBar = this.$refs.table.$el.querySelector(&#39;.el-scrollbar__wrap&#39;); if (scrollBar) { scrollBar.addEventListener(&#39;scroll&#39;, this.handleScroll); } }); }, beforeDestroy() { const scrollBar = this.$refs.table.$el.querySelector(&#39;.el-scrollbar__wrap&#39;); if (scrollBar) { scrollBar.removeEventListener(&#39;scroll&#39;, this.handleScroll); } }, methods: { handleScroll() { const scrollLeft = this.$refs.table.$el.querySelector(&#39;.el-scrollbar__wrap&#39;).scrollLeft; const header = this.$refs.table.$el.querySelector(&#39;.el-table__header&#39;); header.style.marginLeft = `-${scrollLeft}px`; }, }, }; </script> ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柳晓黑胡椒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值