React实现滑动选择插件(仿Antd-mobile Picker)

本文介绍了如何使用React实现一个滑动选择插件,类似于Antd-mobile的Picker组件。通过分析组件结构,确定参数和数据结构,逐步制作PickerView和PickerColumn,最后完成Picker组件的制作,包括级联效果、手势识别和动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图

clipboard.png

需求

由于移动端iOS和安卓原生select样式和效果不同,同一个控件在不同系统上效果不同。
所以决定制作一个跟iOS风格类似的,可以滚动,选择器插件。
之后看到了antd-mobile里面的picker插件符合我们的要求,使用了一段时间感觉其效果不错,隧查看源码,探究其制作过程。
但是antd-mobile是Typescript编写的,跟React类似,但是又不太一样。所以基本是关键问题查看其做参考,剩下的自己实现。

Step1 组件分析

经过查看和分析后 可以得出结论(如下图)

clipboard.png

该组件(Picker)大致分成3个部分

  1. children 触发组件弹出的部分,一般为List Item。其实就是该组件的this.props.children。

  2. mask 组件弹出之后的遮罩,点击遮罩组件消失,值不变(相当于是点击取消)。

  3. popup 组件弹出之后的内容,分成上下两个部分,其中下半部分是核心(antd-mobile中将其单独提出来 叫做PickerView)。

第3部分PickerView即为极为复杂,考虑到扩展性:
这里面的列数是可变的(最多不能超过5个);
每一列滚动结束 其后面的列对应的数组和默认值都要发生改变;
每一列都是支持滚动操作的(手势操作)。
组件化之后如图:

clipboard.png

分析之后可以看出 第3部分是该组件的核心应该优先制作。

Step 2 使用方法确定

在做之前应该想好输入和输出。
该组件需要哪些参数,参数多少也决定了功能多少。
参照antd-mobile的文档 确定参数如下:

  1. data:组件的数据源 每列应该显示的数据的一个集合 有固定的数据结构

  2. col:组件应该显示的列数

  3. value:默认显示的值 一个数组 每一项对应各个列的值

  4. text:popup组件中间的提示文字

  5. cancelText:取消按钮可自定义的文字 默认为取消

  6. confirmText:确定按钮自定义的文字 默认为确定

  7. cascade:是否级联 就是每一列的值变化 是否会影响其后面的列对应数组和值得变化 是否级联也会影响到数据源数据结果的不同

  8. onChange:点击确定之后 组件值发生变化之后的回调

  9. onPickerChange:每一列的值变化之后的回调

  10. onCancel:取消之后的回调

参数确定之后要确定两个核心参数的数据结构
级联时候data的数据结构

const areaArray = [
    {label: '北京市', value: '北京市', children: [
        {label: '北京市', value: '北京市', children: [
            {label: '朝阳区', value: '朝阳区'},            {label: '海淀区', value: '朝阳区'},            {label: '东城区', value: '朝阳区'},            {label: '西城区', value: '朝阳区'}
        ]}
    ]},    {label: '辽宁省', value: '辽宁省', children: [
        {label: '沈阳市', value: '沈阳市', children: [
            {label: '沈河区', value: '沈河区'},            {label: '浑南区', value: '浑南区'},            {label: '沈北新区', value: '沈北新区'},        ]},        {label: '本溪市', value: '本溪市', children: [
            {label: '溪湖区', value: '溪湖区'},            {label: '东明区', value: '东明区'},            {label: '桓仁满族自治县', value: '桓仁满族自治县'},        ]}
    ]},    {label: '云南省', value: '云南省', children: [
        {label: '昆明市', value: '昆明市', children:[
            {label: '五华区', value: '五华区'},            {label: '官渡区', value: '官渡区'},            {label: '呈贡区', value: '呈贡区'},        ]}
    ]},];

对应value的数据结构:['辽宁省', '本溪市', '桓仁满族自治县’]
不级联的时候 data则为

const numberArray = [
    [
        {label: '一', value: '一'},        {label: '二', value: '二'},        {label: '三', value: '三'}
    ],    [
        {label: '1', value: '1'},        {label: '2', value: '2'},        {label: '3', value: '3'},        {label: '4', value: '4'}
    ],    [
        {label: '壹', value: '壹'},        {label: '貮', value: '貮'},        {label: '叁', value: '叁'}
    ]
];

此时value为:['一', '4', '貮’]

Step 3 PickerView制作

Picker组件的核心就是PickerView组件
PickerView组件里面每个列功能比较集中,重用程度较高,故将其封装成PickerColumn组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值