当前位置:

react-native 封装城市选择组件二

访客 2024-04-22 550 0

今天我进一步进行完善,主要是把暴露的接口写完了,我还会进一步完善,如果在项目中跑起来没什么问题的话,我就会上传到npm,以供大家学习和使用,当然如果能封装更好的,大家可以一块学习。

一、props

下面看props

  1. data这个参数必传。跟SectionList相似,只不过我的数组属性是items,而SectionList的是data
[{...items:[]}]
  • selectedIndexes初始化已选中的下标,如:
  • //这里面的元素个数取决于你的总列数[0,0,0]//代表选中第一列的第一个,第二列的第一个,第三列的第一个[2,1,0]//代表选中第一列的第三个,第二列的第二个,第三个的第一个//加入说你传入的是[1]那么就会选中第一列的第二个,第二列的第二个,第三列的第二个,也就相当于[1,1,1]//如果传入的是[1,2]那么就会选中第一列的第二个,第二列的第三个,第三列的第三个,也就相当于[1,2,2]//如果不传,就默认:[0,0,0]
  • renderItems,renderItem这个参数必传。这个就是FlatListrenderItem,这两个的优先级renderItems>renderItem
  • //如果传入的renderItem而没有传入renderItems,//那么所有列都使用相同的renderItem,否则按照renderItems数组里面的渲染各自的//先假设总的列数是n//渲染规则跟上面的selectedIndexes相同//比如[()=>null],相当于[()=>,()=>null,()=>null]//比如[()=>null,()=><Text>test</Text>],相当于[()=>null,()=><Text>test</Text>,()=><Text>test</Text>]//值得说的是回调的参数//({item,index,isSelected})=>null//其中item代表每一列的每一项数据//index代表下标//isSelected代表当前行是否被选中
  • n这个就是代表总列数,这个参数必传
  • style最外面容器的样式。
  • widthRadio这个是每一列的宽度占比。
  • //比如:['30%','30%','30%'],那么就代表三列的宽度都是屏幕宽度的一半//比如:[240,'40%'],那么代表第一列240,第二列占屏幕的宽度百分之四十//如果有缺省值,也就是传入n>数组的长度,比如n我传入的是5,而数组['30%','30%','30%'],//那么相当于['30%','30%','30%','30%','30%']这样的话有些列就不会在屏幕上显示,只需要滑动就能看到
  • flatListContainerStyle这个代表所有列的容器的样式。
  • ListHeaderComponent跟FlatList相似,只不过不同的是这个不会随着列表的上下滑动而滑动。
  • ListFooterComponent同上。
  • styles这个代表每一个FlatListstyle,目前的功能是一个一个地对应的,以后也会像上面的selectedIndexes一样。
  • moreFlatListProps这个是FlatListprops,也是一个一个地对应的,同样以后会实现像上面的效果。
  • scrollViewProps这个就是ScrollViewprops
  • itemPress这个就是每一项的点击事件。
  • //itemPress回调的参数就是每一列的数据,除items外的数据,像下面实现:constitemPress=(item,i)=>{}//这里面的i是代表第几列,第一列是0以此类推。二、效果图

    三、示例代码constDefaultPicker=(props)=>{constrenderItemTitle=useCallback(({item,index,isSelected})=>{conststyle={borderLeftWidth:4,borderLeftColor:isSelected?colors.primary:'#fff',backgroundColor:isSelected?'#F8F8F8':'#fff',};return(<Viewstyle={style}><Textkey={index}style={styles.itemTitleStyle}>{item?.name||''}</Text></View>);},[]);constrenderItemOther=useCallback(({item,index,isSelected})=>{conststyle={color:isSelected?colors.primary:'#505050',};return(<Textkey={index}style={[styles.itemOtherStyle,style]}>{item?.name||''}</Text>);},[]);return(<Viewstyle={styles.fullscreen}><Viewstyle={styles.fullscreen}/><Picker{...props}style={styles.pickerStyle}styles={[styles.f1BgColor,styles.f23BgColor,styles.f23BgColor]}ListHeaderComponent={()=>ListHeaderComponent(props.disappear)}renderItems={[renderItemTitle,renderItemOther]}n={3}moreFlatListProps={[{keyExtractor:(item,index)=>itemindex},{keyExtractor:(item,index)=>itemindex},{keyExtractor:(item,index)=>itemindex},]}/></View>);};四、源码importReact,{useCallback,useState}from'react';import{ScrollView,View,StyleSheet,FlatList,Dimensions,Pressable,}from'react-native';constselectData=(index,indexes,data)=>{lettempData=data;for(leti=0;i<index;i){tempData=tempData?.[indexes[i]]?.items||[];}returntempData;};/***初始化已经选择的数组*@param{Array<number>}selectedIndexes传入的已经选择的下标*@param{number}n列的个数*/constinitSelectedIndexes=(selectedIndexes=[],n)=>{consttempIndexes=[...selectedIndexes];for(leti=selectedIndexes?.length||0;i<n;i){tempIndexes.push(0);}returntempIndexes;};/***得到模拟数组*@param{number}n所有数据*/constgetSimulateArray=(n)=>{returnnewArray(n).fill(1);};/****@param{Array<number|string>}widthRadio各宽度比例*/constgetWidths=(widthRadio,n)=>{constwidth=Dimensions.get('screen').width;constlen=widthRadio?.length||0;consttempWidths=[];for(leti=0;i<len;i){if(typeofwidthRadio[i]==='string'){constradio=parseFloat(widthRadio[i])/100;tempWidths.push(width*radio);}else{tempWidths.push(widthRadio[i]);}}//如果还有没有添加到数组中的就默认使用最后一个宽度,如果前面都没有值//,那么就定义宽度为总宽度的1/3constequalWidth=tempWidths[tempWidths.length-1]||parseFloat((width/3).toFixed(2));for(letj=len;j<n;j){tempWidths.push(equalWidth);}returntempWidths;};constgetComponent=(ele=null)=>{lettemp;if(typeofele==='function'){temp=ele;}else{temp=()=>ele;}returntemp;};constgetRenderItem=(renderItems=[],n)=>{if(!renderItems){thrownewError('您至少传入一个renderItem');}consttempRenderItems=[];if(Array.isArray(renderItems)){tempRenderItems.push(...renderItems);}else{tempRenderItems.push(renderItems);}constlen=tempRenderItems.length;constsameRenderItem=tempRenderItems[len-1];for(leti=len;i<n;i){tempRenderItems.push(sameRenderItem);}returntempRenderItems;};/***@typedef{{*data:Array,*selectedIndexes?:Array<number>,*renderItems:Array<({item:any,index:number,isSelected:boolean})=>React.ReactElement>,*renderItem:{item:any,index:number})=>React.ReactElement,*styles?:Array<import('react-native').ViewStyle>,*style?:import('react-native').ViewStyle,*flatListContainerStyle?:import('react-native').ViewStyle,*widthRadio?:Array<number|string>,*ListHeaderComponent?:()=>React.ReactElement|import('react').ReactElement|null,*ListFooterComponent?:()=>React.ReactElement|import('react').ReactElement|null,*moreFlatListProps?:Array<import('react-native').FlatListProps>,*scrollViewProps?:import('react-native').ScrollViewProps,*n:number,*itemPress?:(item:any,n:number)=>void*}}PickerType*@param{PickerType}param0*/constPicker=({data,selectedIndexes,renderItems,renderItem,style,flatListContainerStyle,widthRadio,ListHeaderComponent,ListFooterComponent,styles,moreFlatListProps,scrollViewProps,n,itemPress,})=>{const[indexes,setIndexes]=useState(initSelectedIndexes(selectedIndexes,n),);constonPress=useCallback((i,index)=>{setIndexes((oldIndexes)=>{oldIndexes[i]=index;for(letj=i1;j<3;j){oldIndexes[j]=0;}return[...oldIndexes];});},[]);consttoRenderItem=useCallback(({item,index},i)=>{constsetItem={...item};deletesetItem.items;return(<PressableonPress={()=>{onPress(i,index);itemPress?.(setItem,i);}}>{getRenderItem(renderItems||renderItem,n)[i]({item,index,isSelected:indexes[i]===index,})}</Pressable>);},[renderItems,renderItem,n,indexes,onPress,itemPress],);return(<Viewstyle={[pickerStyles.container,style]}>{getComponent(ListHeaderComponent)()}<ScrollView{...scrollViewProps}horizontal={true}><Viewstyle={[pickerStyles.listContainer,flatListContainerStyle]}>{getSimulateArray(n).map((_,index)=>{return(<FlatList{...(moreFlatListProps?.[index]||{})}style={[pickerStyles.flatListStyle,styles?.[index]||{},{width:getWidths(widthRadio,n)[index]},]}data={selectData(index,indexes,data)}renderItem={({item,index:i})=>toRenderItem({item,index:i},index)}/>);})}</View></ScrollView>{getComponent(ListFooterComponent)()}</View>);};constpickerStyles=StyleSheet.create({container:{flex:1,},listContainer:{flex:1,flexDirection:'row',backgroundColor:'#fff',},flatListStyle:{height:'100%',},});exportdefaultReact.memo(Picker);

    这篇主要是介绍props的和我实战的实例。以后还会完善,最终要达到上传到npm的目的。如果以后在使用过程中遇到性能的问题我也会进行优化。

    发表评论

    • 评论列表
    还没有人评论,快来抢沙发吧~