此文前端框架使用 rax,全篇代码暂未开源(待开源)
原文链接地址:Nealyang/PersonalBlog
前言
貌似在面试中,你如果设计一个 react/vue 组件,貌似已经是司空见惯的问题了。本文不是理论片,更多的是自己的一步步思考和实践。文中会有很多笔者的思考过程,欢迎评论区多多交流和讨论。
从需求讨论、技术方案探讨到编码、到最终的测试,经历过了很多次的脑暴,也遇到过非常多的坑,其中有可能跟业务有关、也有可能跟框架有关,基于这些坑,又讨论了很多解决方案和非常 hack(歪门邪道)的对策。但是随着时间的推移,再回头看看当时的 hack 代码,很多都不太记得为什么这么写了,所以这里简单记录下,Filter 组件的开发过程。以便后面查询,更希望能大家一起探讨,以求得更优质的代码架构和实现思路。
由于代码编写使用基于底层 weex 的 rax 框架,所以有些坑,或许对于正在使用 react 或者 vue 的你并不会遇到,可以直接忽略
说说业务
Filter,已经常见的不可再常见的组件了,顾名思义,就是个筛选过滤器。我们先看看现有 app 上的一些 filter 展现 形式。既然做组件,我们就需要它足够的通用,足够的易于扩展。
- 阿里拍卖的 Filter
- 飞猪的 Filter
在说 Filter 的业务特征之前,我们先约束下每一部分的命名,以便于你更好的阅读此文:
上面分别是拍卖和飞猪的 filter 页面,从这两个页面中,我们大概可以总结出关于 Filter 的一下几点业务画像:
- 随着页面滚动,Filter 可能具有吸附能力,但是可能距离顶部存在一定的距离
- Panel 面板多样性(点击navItem 展开的面板)
- Panel 面板以及 navItem 都可能会有动画
- navBar 内容可变
- panel 面板展示形式不定
- panel 面板内容可能非常复杂,需要考虑性能优化
- navBar 上可能存在非 Filter 的内容(关注按钮)
- 有的navBar 的 navItem 没有对应的 panel 面板
- Filter 上存在影响搜索结果但是没有影响的”快排“按钮
- filter 配置参数能够指定
- 通过 url 传入相关筛选 id 能够初始化面板选中
- ...
最终组件产出
由于 rax 1.0 ts+hooks 开源版本还在开发中,所以仓库链接暂时就不放上了
- rax-pui-filter-utils : Filter 的内部工具库,仅供 Filter 开发者提供的工具库
- rax-pui-filter-tools:配合使用 Filter 的一些工具集,比如 提高性能的 HOC 组件、占位符组件等(可用可不用,根据自己业务需求来),思考原由:并不是每一个 Filter 的使用者都需要这些功能,做成可插拔式,为了降低没必要的 bundle 大小
- pui-filter:Filter 核心功能开发库
效果图:
console
处可见抛出的查询参数
设计与思考
前端组件架构图(初版)
组件架构图(终板)
src
├─ Filter.js //Filter 最外层父容器
├─ constant.js //项目代码常量定义
├─ index.js //入口文件
├─ navbar // navBar 文件夹
│ ├─ NavBase.js //navBar 基类 NavQuickSearch 和 NavRelatePanel 父类
│ ├─ NavQuickSearch.js // 快速搜索(无 panel)的 navBar
│ ├─ NavRelatePanel.js // 带有 panel 的 navBar
│ └─ index.js // 导出文件
├─ panel
│ └─ index.js // panel 面板组件代码
└─ style.js
组件功能 Feature
- 筛选头 UI 可动态配置扩展,支持点击动画,提供三种筛选项类型
RelatePanel
:筛选项关联Panel型,即筛选头和 Panel 是一对一关系,点击筛选头展示 PanelQuickSearch
:筛选项快速搜索排序型,即筛选头没有对应 Panel,点击筛选头直接触发搜索PureUI
:纯 UI占位类型,即纯 UI 放置,不涉及搜索,比如订阅按钮场景
- 筛选面板显示隐藏统一管理,支持下拉和左滑展示隐藏动画,统一搜索回调函数
- Filter 组件在和业务面板隔离,支持任意组件接入,业务组件里搜索变更通过
onChange(params)
回调函数来触发 - 提供了三种业务通用的面板组件
rax-pui-list-select
,列表选择业务面板rax-pui-location-select
,省市区级联选择业务面板rax-pui-multi-selection-panel
,多选业务面板,查看组件使用文档
这里指的是 Filter 的功能 Feature,跟上文提及的 Filter 组件功能可能并不能完全覆盖,但是我们提供解决方案,组件的设计始终秉持着不侵入业务的原则,所有与业务相关均给予配置入口。
期望组件使用形式
import Filter from 'rax-pui-filter';
render(
<Filter
navConfig={[]}
onChange={()=>{}}>
<Filter.Panel>
<业务组件1 />
</Filter.Panel>
<Filter.Panel>
<业务组件2 />
</Filter.Panel>
</Filter>
);
组件功能与业务需求边界划分
何为业务功能何为组件功能,这个需要具体的探讨,其实也没有严格意义上的区分。说白了,就是你买个手机,他都会送你充电器。但是。。。为什么很多手机也送手机壳(小米、华为、荣耀)但是 iPhone 却不送呢?所以到底是不是标配?
对于我们这个组件,简而言之:我们能做到的,我们都做!但是其中我们还是梳理出某些功能还是数据业务功能:
- navBar 上每一个 navItem 展示什么文案、样式属于业务功能
- 整个 Filter 的数据处理,包括 url 上的查询参数需要抛给对应 navItem要展示的文案也是业务功能
- Filter 是否点击滚动到顶部也是业务功能,毕竟很多搜索页 Filter 本身置顶。而且,对于 rax 而言,不同容器滚动方式还不同(但是我们提供这样的方法给你去调用)
- panel 面板里面数据请求、逻辑处理都是你自己的业务逻辑。Filter 只提供基本的容器能力和接口
换言之,Filter 里面任何功能都可以说为业务功能。但是我们需要提供 80%业务都需要的功能封装作为 Filter 的 Future。这就是我们的目的。
根据上面的业务功能和组件功能的区分,我们就知道在使用 Filter 的时候,你应该给我传递什么配置,以及什么方法。
Filter API
参数 | 说明 | 类型 | 默认值(是否必填) |
---|---|---|---|
navConfig | 筛选头配置, 点击查看详细配置项 效果图 |
Array<Object> | - (必填) |
offsetTop | Filter组件展开面板状态下距离页面顶部的高度,有两种状态:固定位置和跟随页面滚动吸附置顶 固定位置 状态下距离页面顶部的高度 跟随页面滚动吸附置顶: 状态下距离页面顶部的高度 效果图 |
Number | 0 |
styles | 配置样式,Filter中所有样式都可使用styl |
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6 | |
【大 中 小】【打印】 【繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部】 | |
上一篇:通俗易懂设计模式解析——命令模式 | 下一篇:一次跨行取款失败,而引发对分布.. |