traojs 封装一个支持onFirstAppear和onAppear的view组件
第一步:基础view
import { View as TaroView } from '@tarojs/components'; import { ViewProps } from '@tarojs/components/types/View'; import dayjs from 'dayjs'; interface iViewsProps extends ViewProps { onAppear?: () => void; onFirstAppear?: () => void; id?: string; throttleTime?: number; } /** 注意唯一className */ const View = (props: iViewsProps) => { const { throttleTime = 1000, ...restProps } = props; const throttle = (fn, wait = 1000) => { if (!fn) { return; } // 上一次执行 fn 的时间 let previous = dayjs().valueOf(); let firstClick = true; // 将 throttle 处理结果当作函数返回 return function (...args) { // 获取当前时间,转换成时间戳,单位毫秒 const now = dayjs().valueOf(); // 将当前时间和上一次执行函数的时间进行对比x // 大于等待时间就把 previous 设置为当前时间并执行函数 fn console.error('now - previous: ', now - previous, firstClick); if (firstClick) { fn && fn.apply(this, args); firstClick = false; previous = dayjs().valueOf(); } else if (now - previous > wait) { previous = now; firstClick = false; fn && fn.apply(this, args); } }; }; const throttledClick = throttle(props?.onClick, throttleTime); return <TaroView {...restProps} onClick={throttledClick} />; }; export default View;
第二步: 封装支持onFirstAppear和onAppear
import TaroView from '@/components/GymComponents/GymView'; import { useRef, useEffect } from 'react'; import Taro, { PageInstance } from '@tarojs/taro'; import { ViewProps } from '@tarojs/components/types/View'; interface iViewsProps extends ViewProps { onAppear?: () => void; onFirstAppear?: () => void; id?: string; } /** 注意唯一className */ const View = (props: iViewsProps) => { const { onAppear, onFirstAppear, className, id } = props; const timeRef = useRef(0); const setTimeId: { current: NodeJS.Timeout | null } = useRef(null); // 监听最顶部元素是否在视野内 useEffect(() => { if (!className && !id) { return; } const observer = Taro.createIntersectionObserver( Taro.getCurrentInstance().page as PageInstance, { thresholds: [0], }, ); setTimeId.current = setTimeout(() => { const el = id ? `#${id}` : `.${className}`; observer.relativeToViewport().observe(el, res => { if (res.intersectionRatio) { onAppear && onAppear(); timeRef.current++; console.error('onAppear',timeRef.current) if (timeRef.current <= 1) { console.error('123123123',123123123) onFirstAppear && onFirstAppear(); } } }); }, 0); return () => { if (observer) { observer.disconnect(); if (setTimeId.current) { clearTimeout(setTimeId.current); setTimeId.current = null; } } }; }, [className, id]); return <TaroView {...props} />; }; export default View;
使用:
import RecordView form "../view" <RecordView id="login_btn" onFirstAppear={()={//doSomething}} onAppear={()={//doSomething}} />