关于设计一个 select 组件的思考,除了基本的 options 接口之外,还需要考虑一些特殊业务场景
- 在 MateralUI、Bootstrap 中的实现
- 在老版本 Antd 中的实现
- 在 Element UI、新 Antd、vuetifyjs 中的实现、
- 现有业务中的实现
options 展示
主要分类以下四种对于 options 的展示策略,展示状态下
- 不允许用户 scroll
- scroll 后不跟随移动
- scroll 后跟随移动
- scroll 后消失
这四种实现方案,分别有对应的一些问题:
- 不允许用户 scroll:这种方案在一些比较传统的 UI 组件库中都是这么使用的,用户体验较差,但是不会有其他的一些边缘 case
- 不跟随 scroll:这个纯属于开发者偷懒了,用户体验极差
- 跟随 scroll:这种方案是最为常见的方案,能够比较完美的符合用户的使用预期。但是也存在一个比较大的问题,就是 展示的层级关系需要注意
- 如果这个 select 是在一个 modal 中进行展示的话,会导致 options 溢出 modal 进行滑动,会造成一个很诡异的现象,而且并不好修复,这中实现需要比较合理的组织我们的 CSS。目前 ElementUI 中就能复现这个问题
- scroll 后消失:这种逻辑可以通过监听 document scroll 来实现,但是如果是在 modal 中触发了 scroll,则会导致 options 突然消失,比如用户选了一个 option,然后导致 modal 中的元素换行,导致了 modal 触发 scroll 事件,用户的体验就是,选择了一个 option,然后 select 的下拉就消失了,这种用户体验也较差
select 排斥关系
展开 options 后,点击其他 select,也有两种类型的交互
- 点开后都展示,如 bulma
- 点开后收起前一个,如其他 Framework
如果 select 的信息并不多,可以都展示,如果并拍了多个 select,为了展示效果还是收起前面打开的 select 更为合适
设计实现
那么为了解决不同业务场景下的需求,我们尽量需要将 API 设计的比较通用,比如至少提供下面的几个 API
- options: T[];
- hideOnBlur: boolean;
- hideOnScroll: boolean;
而且个人理解最佳的解决方案应该是:
- 在较小范围内的 scroll 时,跟随滑动
- 如果超过 limit,则隐藏展开 options
这里 scroll 的判断可能会存在判断的逻辑问题,如果我们以 html 为 eventListener的话,会在 html scroll 的时候意外影响我们的判断,所以需要选择一个比较合适的判断目标
关于设计一个 select 组件的思考,除了基本的 options 接口之外,还需要考虑一些特殊业务场景
options 展示
主要分类以下四种对于 options 的展示策略,展示状态下
这四种实现方案,分别有对应的一些问题:
select 排斥关系
展开 options 后,点击其他 select,也有两种类型的交互
如果 select 的信息并不多,可以都展示,如果并拍了多个 select,为了展示效果还是收起前面打开的 select 更为合适
设计实现
那么为了解决不同业务场景下的需求,我们尽量需要将 API 设计的比较通用,比如至少提供下面的几个 API
而且个人理解最佳的解决方案应该是:
这里 scroll 的判断可能会存在判断的逻辑问题,如果我们以 html 为 eventListener的话,会在 html scroll 的时候意外影响我们的判断,所以需要选择一个比较合适的判断目标