短视频app源码,Vue3滚动加载

短视频app源码,Vue3滚动加载

Hooks useLazyLoad

 

 

interface UseLazyLoadQo<T> {
  className: string; // 监听的dom的class
  calcBottomCount: number; // 计算滚动到table底部的次数
  data: T[]; // 数据
  getData: () => void | Promise<void>; // 获取数据的方法
}
interface UseLazyLoadVo<T> {
  updateData?: (nextData: T[]) => void;
}
export const useLazyLoad = <T>(params: UseLazyLoadQo<T>): UseLazyLoadVo<T> => {
  try {
    const { className, data, getData, calcBottomCount } = params || {};
    let list = data;
    let oldScrollTop = 0; // 记录上一次滚动的位置
    let listenDom;
    onMounted(() => {
      listenDom = document.getElementsByClassName(className)[0];
      console.log("mounted", listenDom);
      listenDom?.addEventListener("scroll", listenScroll);
    });
    const updateData = (nextData: T[]): void => {
      list = nextData;
    };
    const listenScroll = (e: Event): void => {
      if (calcBottomCount === 1 && !list.length) return;
      const target = e.target as EventTarget & HTMLDivElement;
      // js有精度问题,所以要向上取整
      const scrollTop = Math.ceil(target?.scrollTop); // 距顶部距离
      const clientHeight = Math.ceil(target?.clientHeight); // 可视区高度
      const scrollHeight = Math.ceil(target?.scrollHeight); // 滚动条总高度
      // 考虑到滚动的位置一般可能会大于一点可滚动的高度,所以这里不能用等于
      // 对比oldScrollTop 与 scrollTop的值,如果相等,说明滚动条没有滚动,直接return
      // console.log('scrollTop', scrollTop, 'clientHeight', clientHeight, 'scrollHeight', scrollHeight);
      if (oldScrollTop === scrollTop) return;
      oldScrollTop = scrollTop;
      if (scrollTop && scrollTop + clientHeight >= scrollHeight) {
        getData && getData();
      }
    };
    onUnmounted(() => {
      removeEventListener("scroll", listenScroll);
    });
    return {
      updateData, // 更新数据
    };
  } catch (error) {
    console.error(error);
    return {
      updateData: undefined,
    };
  }
}; 

使用:

 


interface MyState {
  appData: any[];
}
const state = reactive<MyState>({
  appData: [],
});
let calcBottomCount = 1; // 计算滚动到table底部的次数(滚动到底部加 1 如果没有数据 就不赋值)
const params = {
  className: 'app-wrap_view',
  data: state.appData,
  getData: getData,
  calcBottomCount,
};
const { updateData } = useLazyLoad<pageListVO>(params);
watch(
  () => state.appData,
  () => {
    // 由于 useLazyLoad 无法监听数据变化,所以需在watch中调用函数
    updateData && updateData(state.appData);
  }
);
const getData = async (): Promise<void> => {
  try {
    const params: pageListQO = {
      current: calcBottomCount,
      productName: '',
      size: 20,
    };
    state.loading = true;
    const res = await xxApi(params);
    state.loading = false;
    
    const { code } = res || {};
    if (code !== RES_CODE.SUCCESS) return;
    const { list } = res.data || {};
    if (!list.length && calcBottomCount > 1) {
      message.warning('没有更多数据了');
      return;
    }
    calcBottomCount++;
    state.appData.push(...(list || []));
  } catch (error) {
    state.loading = false;
    console.error(error);
  }
};

 

 以上就是短视频app源码,Vue3滚动加载, 更多内容欢迎关注之后的文章

 

posted @ 2023-11-06 14:00  云豹科技-苏凌霄  阅读(41)  评论(0编辑  收藏  举报