Bootstrap

vue实现滚动条滑动到底部分页调取后端接口加载数据

一、案例效果

在这里插入图片描述

二、前提条件

接口返回数据
在这里插入图片描述

三、案例代码

子组件

const $emit = defineEmits(['cloneItem', 'updateList']);

const props = defineProps({
  rightList: {
    type: Array,
  },
  chartTableData: {
    type: Array as () => ChartListType[],
  },
  deleteChartInfo: {
    type: Object,
  },
  chartPageInfo: {
    type: Object,
  },
});


const isLoading = ref(false);
const cardList = ref<any>([]);
const page = ref(1);
const chartPageDetail = ref<any>({});

const hasMoreData = ref(true); // 添加标志位

const loadMoreData = async () => {
  if (isLoading.value) return;
  isLoading.value = true;
  // 模拟异步加载数据
  setTimeout(async () => {
    page.value++;
    await $emit('updateList', { pageNum: page.value, pageSize: 10 });

    if (page.value >= chartPageDetail.value.totalPage) {
      hasMoreData.value = false; // 更新标志位
      isLoading.value = false;
      return;
    }
    isLoading.value = false;

    // 确保滚动条与底部保持一定距离
    const drawerContent = document.querySelector('.drawer-content');

    if (drawerContent) {
      drawerContent.scrollTop = drawerContent.scrollHeight - drawerContent.clientHeight - 100;
    }
  }, 1000);
};

const handleScroll = () => {
  const drawerContent = document.querySelector('.drawer-content');
  if (drawerContent) {
    const { scrollTop, scrollHeight, clientHeight } = drawerContent;
    if (scrollTop + clientHeight >= scrollHeight - 50 && !isLoading.value && hasMoreData.value) {
      loadMoreData();
    }
  }
};

onMounted(() => {
  const drawerContent = document.querySelector('.drawer-content');
  if (drawerContent) {
    drawerContent.addEventListener('scroll', handleScroll);
  }
});

onBeforeUnmount(() => {
  const drawerContent = document.querySelector('.drawer-content');
  if (drawerContent) {
    drawerContent.removeEventListener('scroll', handleScroll);
  }
});

watch(
  () => props.chartTableData,
  () => {
    const tableData = JSON.parse(JSON.stringify(props.chartTableData));
    cardList.value = [...cardList.value, ...tableData];
    console.log('76-- cardList.value', cardList.value);
  },
  { immediate: true, deep: true },
);

watch(
  () => props.chartPageInfo,
  () => {
    if (props.chartPageInfo) {
      chartPageDetail.value = { ...props.chartPageInfo };
    }
  },
  { immediate: true, deep: true },
);

父组件

  <DrawerContent
    :rightList="rightList"
      :chartTableData="chartTableData"
      :chartPageInfo="chartPageInfo"
      :deleteChartInfo="deleteChartInfo"
      @updateList="updateChartList"
    />

const chartPageInfo = ref({});

/**
 * 查询图表列表
 */
const getChartList = async (paramsVal?: { pageNum: number; pageSize: number }) => {
  const params = paramsVal
    ? { ...paramsVal }
    : {
        pageNum: 1,
        pageSize: 10,
      };
  const res = await net.strategyManageApi.getChartListApi({ ...params });
  if (res.data.code === 0) {
    chartTableData.value = res.data?.data?.data || [];

    console.log('151---chartTableData', chartTableData.value, '151----rightList', rightList.value);
    chartTableData.value = formatChartTableData(chartTableData.value, rightList.value);
    chartPageInfo.value = {
      pageSize: res.data?.data.pageSize,
      totalNum: res.data?.data.totalNum,
      totalPage: res.data?.data.totalPage,
    };
  }
};

const updateChartList = async (params: { pageNum: number; pageSize: number }) => {
  await getChartList(params);
};

/**
 * 格式化左侧图表列表-添加isAdd属性
 * @param chartTableData: 左侧图表列表
 * @param rightList: 右侧回显列吧
 * @returns
 */
export const formatChartTableData = (chartTableData: any, rightList: any) => {
  rightList.forEach((rightItem: any) => {
    chartTableData.forEach((tableItem: any) => {
      if (rightItem.id === tableItem.id) {
        tableItem.isAdd = true;
      }
    });
  });
  return chartTableData;
};

;