记一个复杂组件(Filter)的从设计到开发

640?wx_fmt=png

640?wx_fmt=gif 640?wx_fmt=png 640?wx_fmt=png由于微信外链限制,推荐阅读等链接无法点击,可点击阅读原文跳转至原文,查看外链。 640?wx_fmt=png 640
 
 

此文前端框架使用 rax,全篇代码暂未开源(待开源)

前言

貌似在面试中,你如何设计一个 react/vue 组件,貌似已经是司空见惯的问题了。本文不是理论片,更多的是自己的一步步思考和实践。文中会有很多笔者的思考过程,欢迎评论区多多交流和讨论。

从需求讨论、技术方案探讨到编码、到最终的测试,经历过了很多次的脑暴,也遇到过非常多的坑,其中有可能跟业务有关、也有可能跟框架有关,基于这些坑,又讨论了很多解决方案和非常 hack(歪门邪道)的对策。但是随着时间的推移,再回头看看当时的 hack 代码,很多都不太记得为什么这么写了,所以这里简单记录下,Filter 组件的开发过程。以便后面查询,更希望能大家一起探讨,以求得更优质的代码架构和实现思路。

由于代码编写使用基于底层 weex 的 rax 框架,所以有些坑,或许对于正在使用 react 或者 vue 的你并不会遇到,可以直接忽略

说说业务

Filter,已经常见的不可再常见的组件了,顾名思义,就是个筛选过滤器。我们先看看现有 app 上的一些 filter 展现 形式。既然做组件,我们就需要它足够的通用,足够的易于扩展。

640?wx_fmt=gif


640?wx_fmt=gif


在说 Filter 的业务特征之前,我们先约束下每一部分的命名,以便于你更好的阅读此文:

640?wx_fmt=jpeg


上面分别是拍卖和飞猪的 filter 页面,从这两个页面中,我们大概可以总结出关于 Filter 的一下几点业务画像:

最终组件产出

由于 rax 1.0 ts+hooks 开源版本还在开发中,所以仓库链接暂时就不放上了

效果图:

640?wx_fmt=gif

console 处可见抛出的查询参数

设计与思考

前端组件架构图(初版)

640?wx_fmt=png

组件架构图(终板)

640?wx_fmt=png
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//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

这里指的是 Filter 的功能 Feature,跟上文提及的 Filter 组件功能可能并不能完全覆盖,但是我们提供解决方案,组件的设计始终秉持着不侵入业务的原则,所有与业务相关均给予配置入口。

期望组件使用形式

 import Filter from 'rax-pui-filter';  render(    <Filter    navConfig={[]}    onChange={()=>{}}>      <Filter.Panel>          <业务组件1 />      </Filter.Panel>      <Filter.Panel>          <业务组件2 />      </Filter.Panel>    </Filter>  );
  render(
    <Filter
    navConfig={[]}
    onChange={()=>
{}}>
      <Filter.Panel>
          <业务组件1 />
      </Filter.Panel>
      <Filter.Panel>
          <业务组件2 />
      </Filter.Panel>
    </Filter>
  );

组件功能与业务需求边界划分

何为业务功能何为组件功能,这个需要具体的探讨,其实也没有严格意义上的区分。说白了,就是你买个手机,他都会送你充电器。但是。。。为什么很多手机也送手机壳(小米、华为、荣耀)但是 iPhone 却不送呢?所以到底是不是标配?

对于我们这个组件,简而言之:我们能做到的,我们都做!但是其中我们还是梳理出某些功能还是数据业务功能:

换言之,Filter 里面任何功能都可以说为业务功能。但是我们需要提供 80%业务都需要的功能封装作为 Filter 的 Future。这就是我们的目的。

根据上面的业务功能和组件功能的区分,我们就知道在使用 Filter 的时候,你应该给我传递什么配置,以及什么方法。

Filter API

参数 说明 类型 默认值(是否必填)
navConfig 筛选头配置, 点击查看详细配置项  

效果图
640?wx_fmt=png
undefined
Array<Object> - (必填)
offsetTop Filter组件展开面板状态下距离页面顶部的高度,有两种状态:固定位置跟随页面滚动吸附置顶

 固定位置 状态下距离页面顶部的高度
  跟随页面滚动吸附置顶: 状态下距离页面顶部的高度

效果图
640?wx_fmt=png
undefined
Number 0
styles 配置样式,Filter中所有样式都可使用styles集合对象来配置覆盖
styles 格式
640?wx_fmt=png
undefined
Object {}
getStickyRef 获取 Sticky 节点的 ref 实例,用于滚动吸附场景,内部配合 pm-app-plus 容器组件点击 Filter 时自动吸附置顶

示例图
640?wx_fmt=png
undefined
Function
keepHighlight 筛选条件改变后是否需要在筛选头保持高亮

效果图
640?wx_fmt=png
undefined
Boolean false
clickMaskClosable 开启 mask 背景的点击隐藏 Boolean true
onChange Filter 搜索变更回调函数
签名: Function(params:Object,index:Number, urlQuery: Object) => void  
参数:
params: Object 搜索参数
index:Number 触发搜索的 Panel 搜索
urlQuery:Object URL query 对象
Function
<
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值