iOUNYU 2025-03-07 12:49 采纳率: 0%
浏览 40

Vue3+elementplus的scrollTop无法获取

Vue3+elementplus
想要获取el-table的滚动条距离顶部的距离来实现活到表格底部时自动加载下一页数据
目前根据下方的代码无法获取到scrollTop,检查问题发现scroll添加的addEventListener无效,滚动发现不会打印123
想知道是为什么以及解决方法是啥

<template>
  <br/>
  <br/>
  <br/>
  <el-table ref="tableRef" :data="tableData" height="300" scrollbar-always-on>
    <!-- 表格列定义 -->
    <el-table-column prop="name" label="姓名"></el-table-column>
    <el-table-column prop="age" label="年龄"></el-table-column>
  </el-table>
  <div>滚动距离顶部:{{ scrollTopDistance }}px</div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount,nextTick } from 'vue';

export default {
  setup() {
    const tableRef = ref(null); // 引用 el-table 组件实例
    const scrollTopDistance = ref(0); // 存储滚动距离
    let scrollBody = null; // 保存滚动容器元素

    const handleScroll = (event) => {
      console.log("123")
      scrollTopDistance.value = event.target.scrollTop;
    };

    onMounted(() => {
      // 确保组件已渲染,获取滚动容器
      // if (tableRef.value) {
      //   // scrollBody = tableRef.value.$el.querySelector('.el-table__body-wrapper');
      //   scrollBody = tableRef.value.$refs.bodyWrapper;
      //   console.log(scrollBody)
      //   if (scrollBody) {
      //     scrollBody.addEventListener('scroll', handleScroll);
      //   }
      // }
      nextTick(() => {
        const scrollableEl = tableRef.value.$el.querySelector('.el-table__body-wrapper');
        if (scrollableEl) {
          scrollableEl.addEventListener('scroll', handleScroll);
        }
      });
    });

    onBeforeUnmount(() => {
      // 组件卸载时移除监听
      if (scrollBody) {
        scrollBody.removeEventListener('scroll', handleScroll);
      }
    });

    return {
      tableRef,
      scrollTopDistance,
      tableData: [{"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},
      {"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},
      {"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},]
    };
  }
};
</script>
<style scoped>
.el-table__body-wrapper {
  overflow-y: auto !important;
}
</style>


  • 写回答

4条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-03-12 04:01
    关注
    让【宝码香车】来帮你解答,本回答参考DeepSeek编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!

    在 Vue3 和 Element Plus 中,el-table 的滚动条是通过 el-table__body-wrapper 元素来实现的。你遇到的问题可能是由于 el-table__body-wrapper 元素在 onMounted 钩子中尚未完全渲染,导致 querySelector 无法正确获取到该元素。

    问题分析

    1. onMounted 钩子中的 DOM 元素可能尚未完全渲染:在 onMounted 钩子中,虽然组件已经挂载,但 el-table 的内部 DOM 结构可能还没有完全渲染完成,导致 querySelector 无法正确获取到 el-table__body-wrapper 元素。

    2. nextTick 的使用nextTick 可以确保在 DOM 更新后执行代码,但有时仍然可能无法捕获到 el-table 的内部 DOM 元素。

    解决方案

    1. 使用 setTimeout 延迟获取 DOM 元素:通过 setTimeout 延迟一段时间,确保 el-table 的内部 DOM 元素已经完全渲染。

    2. 使用 MutationObserver 监听 DOM 变化:通过 MutationObserver 监听 DOM 变化,确保在 el-table__body-wrapper 元素渲染完成后添加事件监听器。

    修改后的代码

    <template>
      <br/>
      <br/>
      <br/>
      <el-table ref="tableRef" :data="tableData" height="300" scrollbar-always-on>
        <!-- 表格列定义 -->
        <el-table-column prop="name" label="姓名"></el-table-column>
        <el-table-column prop="age" label="年龄"></el-table-column>
      </el-table>
      <div>滚动距离顶部:{{ scrollTopDistance }}px</div>
    </template>
    
    <script>
    import { ref, onMounted, onBeforeUnmount } from 'vue';
    
    export default {
      setup() {
        const tableRef = ref(null); // 引用 el-table 组件实例
        const scrollTopDistance = ref(0); // 存储滚动距离
        let scrollBody = null; // 保存滚动容器元素
    
        const handleScroll = (event) => {
          console.log("123");
          scrollTopDistance.value = event.target.scrollTop;
        };
    
        onMounted(() => {
          // 使用 setTimeout 延迟获取 DOM 元素
          setTimeout(() => {
            const scrollableEl = tableRef.value.$el.querySelector('.el-table__body-wrapper');
            if (scrollableEl) {
              scrollableEl.addEventListener('scroll', handleScroll);
              scrollBody = scrollableEl; // 保存滚动容器元素
            }
          }, 100); // 延迟 100ms
        });
    
        onBeforeUnmount(() => {
          // 组件卸载时移除监听
          if (scrollBody) {
            scrollBody.removeEventListener('scroll', handleScroll);
          }
        });
    
        return {
          tableRef,
          scrollTopDistance,
          tableData: [
            {"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},
            {"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},
            {"name":"张三","age":18},{"name":"李四","age":20},{"name":"王五","age":22},
          ]
        };
      }
    };
    </script>
    
    <style scoped>
    .el-table__body-wrapper {
      overflow-y: auto !important;
    }
    </style>
    

    解释

    1. setTimeout 延迟:通过 setTimeout 延迟 100ms,确保 el-table 的内部 DOM 元素已经完全渲染。

    2. **保存 scrollBody**:在 onMounted 钩子中保存 scrollBody,以便在 onBeforeUnmount 钩子中正确移除事件监听器。

    其他注意事项

    • 如果 el-table 的数据是异步加载的,可能需要进一步调整延迟时间或使用 MutationObserver 来监听 DOM 变化。
    • 如果 el-table 的高度是动态变化的,也需要确保在高度变化后重新绑定事件监听器。

    通过这些调整,你应该能够正确获取 el-table 的滚动条距离顶部的距离,并实现滚动到底部时自动加载下一页数据的功能。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月7日