[inula-dev-tools]<feat> 显示列表组件合入

This commit is contained in:
13659257719 2023-11-07 11:06:56 +08:00
parent 7218f60037
commit 527c502398
3 changed files with 26 additions and 9 deletions

View File

@ -20,7 +20,7 @@
export default class ItemMap<T> { export default class ItemMap<T> {
// 不要用 indexOf 进行位置计算,它会遍历数组 // 不要用 indexOf 进行位置计算,它会遍历数组
private lastRenderItemToIndexMap: Map<T, number>; private lastRenderItemToIndexMap: Map<T | undefined, number>;
constructor() { constructor() {
this.lastRenderItemToIndexMap = new Map(); this.lastRenderItemToIndexMap = new Map();
@ -34,10 +34,10 @@ export default class ItemMap<T> {
return nextItems; return nextItems;
} }
const nextRenderItems: T[] = []; const nextRenderItems: (T | undefined)[] = [];
const length = nextItems.length; const length = nextItems.length;
const nextRenderItemToIndexMap = new Map<T, number>(); const nextRenderItemToIndexMap = new Map<T | undefined, number>();
const addItems = []; const addItems: T[] = [];
// 遍历 nextItems 找到复用 item 和新增 item // 遍历 nextItems 找到复用 item 和新增 item
nextItems.forEach(item => { nextItems.forEach(item => {

View File

@ -48,7 +48,7 @@ function parseTranslate<T>(data: T[], itemHeight: number) {
export function VList<T extends { id: number | string }>(props: IProps<T>) { export function VList<T extends { id: number | string }>(props: IProps<T>) {
const { data, maxDeep, height, width, children, itemHeight, scrollToItem, onRendered } = props; const { data, maxDeep, height, width, children, itemHeight, scrollToItem, onRendered } = props;
const [scrollTop, setScrollTop] = useState(Math.max(data.indexOf(scrollToItem), 0) * itemHeight); const [scrollTop, setScrollTop] = useState(Math.max(data.indexOf(scrollToItem!), 0) * itemHeight);
const renderInfoRef: { current: RenderInfoType<T> } = useRef({ const renderInfoRef: { current: RenderInfoType<T> } = useRef({
visibleItems: [], visibleItems: [],
}); });
@ -75,7 +75,7 @@ export function VList<T extends { id: number | string }>(props: IProps<T>) {
const index = data.indexOf(scrollToItem); const index = data.indexOf(scrollToItem);
// 显示在页面中间 // 显示在页面中间
const top = Math.max(index * itemHeight - height / 2, 0); const top = Math.max(index * itemHeight - height / 2, 0);
containerRef.current.scrollTo({ top: top }); containerRef.current?.scrollTo({ top: top });
} }
} }
}, [scrollToItem]); }, [scrollToItem]);
@ -87,9 +87,9 @@ export function VList<T extends { id: number | string }>(props: IProps<T>) {
setScrollTop(scrollTop); setScrollTop(scrollTop);
}; };
const container = containerRef.current; const container = containerRef.current;
container.addEventListener('scroll', handleScroll); container?.addEventListener('scroll', handleScroll);
return () => { return () => {
container.removeEventListener('scroll', handleScroll); container?.removeEventListener('scroll', handleScroll);
}; };
}, []); }, []);
@ -117,7 +117,7 @@ export function VList<T extends { id: number | string }>(props: IProps<T>) {
} }
return ( return (
<div <div
key={String(i)} // 固定 key 值,这样就只会更新 translateY 的值 key={String(index)} // 固定 key 值,这样就只会更新 translateY 的值
className={styles.item} className={styles.item}
style={{ transform: `translateY(${itemToTranslateYMap.get(item)}px)` }} style={{ transform: `translateY(${itemToTranslateYMap.get(item)}px)` }}
> >

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
*
* openInula is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export { VList } from './VList';
export type { RenderInfoType } from './VList';