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

我们提供基础的动画配置,但是同时,也提供动画的 functionHook,这些都取决于动画的触发时机

get animationConfig() { const { animation } = this.props; if (!animation || !is('Object')(animation)) { return PANEL_ANIMATION_CONFIG; } return Object.assign({}, PANEL_ANIMATION_CONFIG, animation); } // ... /** * 执行动画 * @param nextProps */ componentWillReceiveProps(nextProps) { if (nextProps.visible !== this.props.visible) { if (nextProps.visible) { setNativeProps(findDOMNode(this.refPanelContainer), { style: { transform: `translateX(-${rem2px(750)})`, }, }); this.props.disableNavbarClick(true); this.enterAnimate(this.currentChildref, () => { this.props.disableNavbarClick(false); }); this.handleMaskAnimate(true); } else { this.handleMaskAnimate(false); this.props.disableNavbarClick(true); this.leaveAnimate(this.currentChildref, () => { this.props.disableNavbarClick(false); setNativeProps(findDOMNode(this.refPanelContainer), { style: { transform: 'translateX(0)', }, }); }); } } }

由于动画的执行需要时间,所以这个时间段,我们应该给 Filter 中的 NavBar 加锁 ,锁的概念也同样提供给用户,毕竟业务逻辑我们是不会侵入的,在上一次的搜索没有结果返回时候,应该给 NavBar 加锁,禁止再次点击(虽然用户可以再 onchange 回调函数中处理,但是作为组件,同样应该考虑并且提供这个能力),同样对于动画也是如此,在该动画正在执行的时候,应该禁止 NavBar 的再次点击。上面的动画配置效果如下:

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

Panel 中还有核心的处理或许就是关于动画时机的处理。比如在触发动画前,我们需要设置动画初始状态,但是如若如下写法,会出现 Panel 闪动的现象,毕竟我们通过第二次的事件轮训回来才执行初始化,所以这里,如果用户配置启动动画,那么我们需要在 Panel 的最外层添加一个可见的 flag:默认进来 opacity 设置为 0,当动画初始状态设置完毕后,在将最外层容器的 opacity 设置为 1,其实 Panel 还是闪了一下,只是你看不到而已。

// 设置动画初始样式 setTimeout(() => { setNativeProps(node, { style: { transform: !visible ? 'translate(0, 0)' : v, }, }); }, 0); // 执行动画 setTimeout(() => { transition( node, { transform: visible ? 'translate(0, 0)' : v, }, { timingFunction: timingFunction, duration: duration, delay: 0, }, cb, ); }, 50);

设置动画初始化样式中添加:

setNativeProps(findDOMNode(this.refPanelContainer), { style: { opacity: 1, }, }); 结束语

Filter 的组件看似简单,但是如果想写一个市场上较为通用和广泛的 Filter 组件,不仅仅是组件的颗粒度、耦合度和性能需要考虑,更多的是其中还是有太多的业务逻辑需要去思考。对于目前的初版(还未修改成正式开源版),已经基本涵盖了目前我们能够想到的业务场景,也已经有相关业务落地使用。

当然,对于如果是直接放到业务中使用而不作为开源组件的话,我们可已经 Panel下的 child 通过 renderPortal 降低层级,通过 EventBus 或者 redux、mobx 等管理数据状态。那样会让整个代码逻辑看起来清晰很多。但是为了降低bundle 大小,我们尽可能的减少通用包的使用以及第三方插件的依赖。

关于文章中没有提及的想法或者对于这些Filter业务需求(坑)你有更好的处理方法和想法都欢迎在评论区交流~

学习交流

关注公众号: 【全栈前端精选】 每日获取好文推荐。

公众号内回复 【1】,加入全栈前端学习群,一起交流。

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzzys.html