我有这样一个需求:
有一个组件是一个基础组件,很多页面都可能用到,
但是有些页面可能会有一些属于自己的特定的逻辑,
这个时候我想到了继承和mixin,将逻辑不一样的地方写到mixin里面
或者继承他的子类,开发中我选择使用了vue提供的mixin,但是存在一个
问题,vue怎么通过判断路由信息来给组件混入不同的mixin呢?或者动态继承也可以。
个人觉得还是动态继承最好,因为可以覆盖父类里面的方法,vue的mixin优先使用父类的方法,无法覆盖。
*解释一下:我试过mixin数组中调用工厂函数然后返回一份mixin,通过在工厂函数中判断路由信息来决定要不要给返回这份mixin,这样就达到了个不同的页面加上属于自己的业务逻辑代码,但是存在一个问题,我在这个工厂函数所在的模块导入了router对象实例,但是当mixin中的工厂函数被调用的时候拿不到对应的路由信息,里面的数据都是null,应该是这个函数调用的太早了###
如果mixin组件只有JS部分,那很好搞,你搞个工厂函数返回一个对象即可,根据不同的参数返回不同的对象。
但是mixin...它本身解决的是组件公共的部分,你好像跑歪了...
###其实你需要的是动态生成组件,只不过你想把逻辑放在 mixin 里面,方便拼接。这样想倒也没有太大问题,但是如果项目比较大,复杂度上去之后,将来的维护会很成问题。
如果 值得 的话,我建议你提升抽象程度,用一种小语言(DSL)来做,会比现在这种 定义规则,按照规则生成对象 更可靠。
至于要实现你想象中的功能,我觉得可以考虑 异步组件,通过一个父组件拼接复合功能需求的子组件来完成。
###首先,你需要整理一下思路。
其实,你的需求并非是怎样去做动态的改变,最根本的在于组件如何解藕。
在此之前,首先需要知道的一点是,相对于高阶组件,mixin的性能要差的多。所以,你应当总是扩展组件定义,而非每次使用extends或者mixins。
对于你的需求,无论是扩展重载,还是完全扩展新增都是可行的。唯一需要注意的是,未正确重载或新增时的错误防止机制。
在此情况下,你可以手写或者jsx方式提供render函数的重载,其他部分如数据等则可利用Vue.config中的全局合并函数去处理。另一种比较常见的方法是使用模版,通过调整参数编译模版为Vue的模版,再通过Vue的template渲染,这应该是一个非常不理想的解决方案,应当尽量避免。
无论在何种情况下,上述扩展组件的方式都是一种强耦合的解决方案。你可以枚举出很多应用场景,但整个组件都是为预先定义好的场景服务的。相当不利于未来的修改和扩展。
因此,需要改变一下思路,把基于一个组件的扩展变为将这个组件拆分为多个组件。
对于你的需求,首先需要定义一个通用架构的组件,这个组件是所有子组件的上层组件,用来解析传入的参数,并选择合适的子组件依赖进行渲染。这个组件不拥有自身的状态,完全通过外部传入参数调节。动态组件就是其中之一。如果需要更复杂的逻辑,可以使用函数式组件实现。
在这个组件下层,你可以将不连续或者想拆分的部分做成多份组件。这些组件就是乐高积木中的常用积木部分。剩下的,还需要针对不同场景制作特定的组件,相当于乐高积木中的主题人物积木。我们称这些专门为场景定义的组件为适配器。适配器组件未必包含完整逻辑,它可能继续包含通用组件,或者其他适配器组件,也可以与其他组件协同工作。
在此设计模式下,所有的组件已被打散原子化。当未来需求变动时,仅需改动部分组件,或者新增适配器组件即可。