vue3下使用elementplus的el-scrollbar美化滚动条及触底加载

<el-scrollbar>有一个触底加载的坑点,就是加载后内容高度增加了,但是滚动条位置没有跟着变化,所以需要用手动触发官方写的setScrollTop方法进行重置,就可以了。

这里我封装成了组件vTable.vue,完整代码如下:

<!-- 无限滚动加载 -->
<template>
  <div class="infinite-scroll">
    <el-scrollbar ref="scrollbarRef" @scroll="onScroll">
      <slot></slot>
    </el-scrollbar>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted, onBeforeUnmount, watch, defineComponent, nextTick, defineEmits } from 'vue'

const emits = defineEmits(["loadData"])
const props = defineProps({
  loading: {
    type: Boolean
  },
  pageNum: { // 判断是否是第一页,如果是第一页则scroll重置到顶部
  }
})

const scrollbarRef = ref()
const state = reactive({
  loading: false,
  _scrollTop: 0, // 记录数据加载前滚动条的位置,用来手动定位scrollbar
})


watch(() => props.pageNum, () => {
  if (props.pageNum == 1) {
    state._scrollTop = 0
    scrollbarRef.value.setScrollTop(state._scrollTop)
  }
})

watch(() => props.loading, () => {
  scrollbarRef.value.setScrollTop(state._scrollTop)
  nextTick(() => {
    state.loading = props.loading
  })
})

const onScroll = (options: any) => {
  if (state.loading === true) {
    return
  }
  // console.log(123, options, scrollbarRef.value.wrapRef.scrollHeight)
  let wrapRef = scrollbarRef.value.wrapRef
  scrollbarRef.value.moveY = wrapRef.scrollTop * 100 / wrapRef.clientHeight
  scrollbarRef.value.moveX = wrapRef.scrollLeft * 100 / wrapRef.clientWidth
  let poor = wrapRef.scrollHeight - wrapRef.clientHeight
  // 判断滚动到底部
  if (options.scrollTop + 2 >= poor) {
    state._scrollTop = options.scrollTop
    emits("loadData", true)
  }
}

</script>

<style lang="scss" scoped>
.infinite-scroll {
  position: relative;
  width: 100%;
  height: 100%;
  overflow-y: auto;
}
</style>

然后在其他文件内使用:

<template>
  <vTable :loading="state.tableLoading" :pageNum="state.pageNum" @loadData="loadData">
    <el-table :data="state.tableData" style="width: 100%">
      <el-table-column prop="" label="项目名称">
        <template #default="scope">
          {{ scope.row.name }}
        </template>
      </el-table-column>
    </el-table>
  </vTable>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted, onBeforeUnmount, watch, defineComponent, nextTick } from 'vue'
import vTable from "@/components/vTable.vue"

const state = reactive({
  tableData: [] as any,
  total: 0,
  tableLoading: false,
  pageNum: 1,
  pageSize: 10,
})

onMounted(() => {
  init()
})

const init = () => {
  // 获取表格数据
  getTableData()
}


// 获取表格数据
const getTableData = () => {
  state.tableLoading = true
  
  API接口({
    pageNum: state.pageNum,
    pageSize: state.pageSize
  })
    .then((res: any) => {
      let data = res.data
      state.tableData = data
      state.total = data.total
      nextTick(() => {
        state.tableLoading = false
      })
    }).catch((err: any) => {
      state.tableLoading = false
    })
}


// 滚动加载表格数据
const loadData = () => {
  if (state.total <= state.tableData.length) {
    return
  }
  state.tableLoading = true
  state.pageNum++
  API接口({
    pageNum: state.pageNum,
    pageSize: state.pageSize
  })
    .then((res: any) => {
      let data = res.data
      state.tableData.push(...data)
      nextTick(() => {
        state.tableLoading = false
      })
    }).catch((err: any) => {
      state.tableLoading = false
    })
}
</script>

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清岚_lxn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值