「類 mixin」 指的是 Vue 中的 mixin,Regular 中的 implement
mixin
的存在?爲了擴展對象(組件)的功能javascript
擴展對象功能的需求是很容易的理解的。好比業務開發時會碰到跨模塊傳遞消息的需求,經常使用的方法是使用 「發佈-訂閱模式」 來建立一個全局的EventEmitter
。不使用 mixin
時的使用方法以下html
// global/eventEmitter class EventEmitter { on(eventName, handle) { } emit(eventName) { } } // ComponentA import EventEmitter from 'global/eventEmitter'; // 全局的 EventEmitter 對象 class ComponentA { constructor() { EventEmitter.on('event', () => {}); } } // ComponentB import EventEmitter from 'global/eventEmitter'; class ComponentB { constructor() { EventEmitter.emit('event'); } }
咱們須要在不一樣的組件中引入 EventEmitter
來使用它前端
若是使用 mixin
的話,咱們能夠這樣作java
// eventEmitter mixin import EventEmitter from 'global/eventEmitter'; // 全局的 EventEmitter 對象 const eventEmitterMixin = { on: (eventName, handle) => {EventEmitter.on(eventName, handle)}, fire: () => {EventEmitter.emit(eventName)} } // Root Component Component.mixin(eventEmitterMixin); // ComponentA class ComponentA { constructor() { this.on('event', () => {}); } } // ComponentB class ComponentB { constructor() { this.emit('event'); } }
這樣經過mixin
來擴展了組件的功能,是每一個組件均可以方便的使用 EventEmitter
的功能react
軟件開發中的 DRY
原則仍是有必要遵照的。過多的重複代碼會致使維護上的麻煩,經過 mixin
,咱們能夠在不一樣的對象上使用同一份代碼來完成相同的功能,減輕咱們維護的壓力。git
其實這兩個沒有可比性,但在咱們決定是否須要將一個對象經過 mixin
的方式混入到其餘對象時就應該考慮這個問題。github
原則上 複用 > 擴展。數據庫
若是一個 mixin
只是爲了擴展單個對象的功能,而擴展的功能並不能複用到其餘的對象時,就不該該使用 mixin
,而是直接寫在那個對象上更好。設計模式
若是擴展的功能能夠被複用的話,那麼能夠考慮使用 mixin
。數據結構
mixins-considered-harmful 這篇文章已經列舉了一些問題,我簡單的列舉下
mixin
會引入隱性的依賴關係mixin
會致使命名衝突mixin
會增長項目的複雜性雖然mixin
有一些缺點,但正確的使用仍是能夠方便咱們的開發沒有不合理的設計模式,只有不合理的使用設計模式
首先咱們須要解決混入的 mixin
可能會形成隱性的依賴關係,而造成這種依賴關係多半是 mixin
中的擴展功能依賴了被擴展對象想內部數據,例如:
// 一個數據庫查看組件 class DatabaseView { state = { database: [{name: 'db1', id: 1, tables: [{name: 'table1', id: 1}]}] } } DatabaseView.mixin(viewTabelDetails); // 把查看錶詳情彈窗做爲 mixin 混入 const mixin = { viewTabelDetails: (dbId, tableId) => { const db = this.state.database.filter(db => db.id === dbId)[0]; if (db) { const table = db.tables.filter(table => table.id === tableId)[0]; if (table) { Model.show(table); } } } }
上面的例子中,mixin
依賴的 DarabaseView
中的 database
數據。這就致使了若是頁面中其餘的組件也須要一個查看錶詳情彈窗的功能,那麼這個組件也必須有相似的 database
數據,造成了一個隱性的依賴關係。
避免的方式就是 mixin
對象中的功能不要與被擴展對象發生依賴,而在組件開發中這個依賴多半就是使用了被擴展對象的 state
產生的
至於命名衝突和增長項目的複雜性能夠經過其餘的方式解決,相比於上面的問題還算簡單
mixin
只是用來擴展對象功能的,並且這個擴展功能是能夠被複用的,不然你應該直接寫在對象裏面mixin
提供的函數不該該依賴被擴展對象的內部數據。由於若是依賴的被擴展對象的內部數據,會使這個 mixin
只能被包含特定數據對象的對象複用,影響 mixin
的複用其實我以爲在前端的開發中,咱們應該避免使用 mixin
去擴展組件的功能
例如咱們徹底可使用函數調用(顯性的)去調用 mixin
對象中的方法,而不是一股腦的將 mixin
對象混合到組件中
每次修改使用了 implement
組件都會特別痛苦(這樣導入的方法 WebStorm 根本不識別),極大了增長維護的工做量。同時因爲有的 mixin
對象依賴的被擴展對象的內部數據,致使想複用的話還得有相同的數據結構(那還複用個錘子啊)
因此,不要用 mixin
!!!
更多文章能夠查看本人的博客 https://lleohao.github.io