titans 2019-06-28
如果你在设计一个工具组件(以下以Vue为背景),希望这个组件能具有更好的适应性,那么你应该兼顾组件的可扩展性与可增强性。
工具组件,本质上来说,是将那些经常重复的代码封装起来,提供一个组件原型,以便复用。高可复用性的一个决定性因素,就是组件不能“写死”,留有配置余地,最终组件的行为应该接受使用者的配置。
一般来说,使用者可以通过两种方式来配置组件:扩展原型和增强原型。
你在原型中预留一些“锚点”,使用者可以在“锚点”中注入自定义的内容,从而改变组件的渲染结果(这类似于参数传递)。或者,使用者继承你的工具组件,覆盖一些能力、增加新的能力等等,得到一个针对性更强的组件(这类似于类继承)。
扩展的最基本特征就是原型不改变。比如:Vue.extend( options )接受一个配置对象,然后返回一个Vue构造函数的“子类”。使用者通过这个子类构造出的组件就具有这些配置,而如果直接通过Vue()
来构造则不具有这些配置。
为了增加可扩展性,我们应该增加“参数”的影响力、灵活性,还要增加可扩展点(“锚点”、可覆盖的方法等)。
另外,减小可扩展点的粒度,有助于降低使用者扩展原型的成本。如果粒度太大(需要向“锚点”填充的内容太多、需要覆盖的方法太复杂),那么使用者就需要向原型注入更多的代码。使用者往往只是想稍微修改(增强)一点默认功能。扩展点的粒度减小以后,使用者只需要选择自己想要修改的那个小部分来配置。
原型本身的行为会受到配置的影响。原型被配置以后,所有从这个原型衍生出来的所有组件都会受到影响。这类似于JavaScript中的原型继承,修改类原型对象会影响所有子对象。
比如:Vue.mixin( mixin ),用它配置Vue以后,创建出的所有组件都会受到影响。
综上所述,“可扩展”和“可增强”是两种不同的能力,在编写可复用组件的时候,应该为使用者同时提供这两种能力。