满口金牙 2022-12-27 14:01 采纳率: 91.1%
浏览 48
已结题

vue 自制滚动条思路请教

对于表格的over-flow滚动条一直没有找到好的解决方案, (会滚动到行的一半的问题, 可以操作scroll 去修正但也不完美 )
即使是Ant design Ui 的table组件,也同样会有滚动到 半行的问题

目前我能想到的方案是:
表格行数是固定的,没有了over-flow
用slice(startRow, startRow + 表格行数) 显示数据,我只要修改startRow值 ,就可以切换数据
问题是需要自制一个滚动条:来更改startRow的值

下面尝试给 table 写一个滚动条 子组件,感觉有些复杂,
请教有什么简单实现的的思路

<template>
    <div ref='scrolldivRef' class='scroll-div' :style="{ 'height': domHeigth + 'px', }" v-if="dataLength > rows">
        <div class="scroll-block mouse-hover"
            :style="{
                'height': scrollBlockHeight + 'px',
                'top': scrollBlockTop + 'px',
            }"
            @mousedown="tst($event)">
        </div>
    </div>
</template>
<script setup lang="ts">
import { computed, ref, onMounted, inject, Ref } from 'vue';
interface Props {
    dataLength: number; // 数据长度
    rows: number; // 表格行数
    domHeigth: number; // 表格的高度(不含表头)
}

const props = withDefaults(defineProps<Props>(), {
    dataLength: 0,
})
const emit = defineEmits<{
    (e: 'changeSelect', value: any): void
}>()

const start_row = inject<Ref<number>>('start_row')! // slice 的第一个参数,即表格的起始行在数据中的index,
const _tempRow = inject<Ref<number>>('_tempRow')! // 当前页中选择的行
const scrolldivRef = ref<HTMLDivElement>()

// 滑动块的高度
const scrollBlockHeight = computed(() => {
    // 一页数据在滑动条所占位置,即滑动块的高度
    const unit = Math.trunc(props.domHeigth / (props.dataLength / props.rows))
    return unit > 10 ? unit : 10
})

// 滑动块距顶的距离
const scrollBlockTop = computed(() => {
    // 顶部数据在滑动条的实际高度
    const top = Math.trunc((props.domHeigth - scrollBlockHeight.value) * (start_row.value + _tempRow.value) / (props.dataLength - 1))
    return top
})

// 拖动 改变start_row------------------------------------------------
let initPointY = 0, moveHeight = 0, init_row = start_row.value, moveRows = 0
function scrollMove(event: any) {
    // 一行数据所占的像素
    const Row = (props.domHeigth - scrollBlockHeight.value) / (props.dataLength - 1)
    moveHeight = event.clientY - initPointY // 移动的垂直距离
    moveRows = Math.trunc(moveHeight / Row)
    // 向上移动至顶部时
    if (start_row.value < 1 && moveHeight < 1) {
        if (_tempRow.value > 0) {
            // emit('changeSelect', moveHeight)
            // _tempRow.value = init_row - moveRows
            // console.log('sssssssss',_tempRow.value)
        }
        return start_row.value = 0
    }
    // 向下移动至底部时
    if (start_row.value >= (props.dataLength - props.rows) && moveHeight > 0) {
        if (_tempRow.value < props.rows - 1) {
            _tempRow.value = _tempRow.value + 1
        }
        return start_row.value = (props.dataLength - props.rows)
    }
    start_row.value = init_row + moveRows
}
function scrollup() {
    init_row = start_row.value
    document.removeEventListener('mousemove', scrollMove)
    document.removeEventListener("mouseup", scrollup); //监听鼠标抬起事件
}

function tst(e: any) {
    initPointY = e.clientY
    document.addEventListener("mousemove", scrollMove) //监听鼠标移动事件
    document.addEventListener("mouseup", scrollup) //监听鼠标抬起事件
}

</script>
<style lang="scss" scoped>
.scroll-div {
    position: absolute;
    right: 0;
    top: 26;
    background-color: antiquewhite;
    width: 20px;

    .scroll-block {
        position: absolute;
        width: 20px;
        background-color: rgb(117, 167, 132);
    }
}
</style>

找到解决办法了, 不用这么复杂,table表格可以固定行,但滑动条完全可以用overflow, 然后把滑动条的 scrollTop 和 数据关联一下就可以了

  • 写回答

4条回答 默认 最新

  • CSDN专家-showbo 2022-12-27 16:30
    关注

    固定行数后实际和分页差不多,显示条数一定,可以计算出页数,滑动条宽度为100/页数,top参数和加载页数有关。设置为当前页-1/页数%基本就差不多了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 1月5日
  • 已采纳回答 12月28日
  • 修改了问题 12月27日
  • 创建了问题 12月27日

悬赏问题

  • ¥15 在若依框架下实现人脸识别
  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同