短影片app原始碼,Vue3滾動載入

zhibo系統開發發表於2023-11-06

短影片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滾動載入, 更多內容歡迎關注之後的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2993081/,如需轉載,請註明出處,否則將追究法律責任。

相關文章