Mixins

類別 mixins 是一種使用標準 JavaScript 在類別之間共用程式碼的模式。與「has-a」組合模式(例如 響應式控制器)不同,在「has-a」組合模式中,類別可以擁有控制器來新增行為,mixins 實作「is-a」組合,其中 mixin 使類別本身成為正在共用的行為的實例。

您可以使用 mixins 來自訂 Lit 元件,方法是新增 API 或覆寫其生命週期回呼。

Mixins 可以被視為「子類別工廠」,它會覆寫套用到的類別並傳回子類別,並使用 mixin 中的行為擴充。由於 mixins 是使用標準 JavaScript 類別表達式實作,因此它們可以使用子類別的所有慣用語,例如新增新的欄位/方法、覆寫現有父類別方法,以及使用 super

為了方便閱讀,本頁上的範例省略了 mixin 函式的一些 TypeScript 型別。如需有關在 TypeScript 中正確設定 mixins 型別的詳細資訊,請參閱TypeScript 中的 Mixins

若要定義 mixin,請撰寫一個採用 superClass 的函式,並傳回一個擴充該類別的新類別,並視需要新增欄位和方法

若要套用 mixin,只需傳遞一個類別,以產生套用 mixin 的子類別。最常見的情況是,使用者會在定義新類別時直接將 mixin 套用至基底類別

Mixins 也可用於建立具體子類別,使用者可以像擴充一般類別一樣擴充這些子類別,其中 mixin 是實作詳細資訊

由於類別 mixins 是一種標準 JavaScript 模式,而非 Lit 特有的模式,因此社群中有很多關於利用 mixins 來重複使用程式碼的資訊。如需有關 mixins 的更多閱讀資料,以下是一些不錯的參考資料

套用至 LitElement 的 Mixins 可以實作或覆寫任何標準的自訂元素生命週期回呼,例如 constructor()connectedCallback(),以及任何響應式更新生命週期回呼,例如 render()updated()

例如,以下 mixin 會在建立、連線和更新元素時記錄

請注意,mixin 應始終對 LitElement 實作的標準自訂元素生命週期方法進行 super 呼叫。當覆寫響應式更新生命週期回呼時,如果父類別上已存在 super 方法,最好呼叫 super 方法(如上所示,對 super.updated?.() 進行選擇性鏈結呼叫)。

另請注意,mixin 可以選擇在標準生命週期回呼的基本實作之前或之後執行工作,方法是選擇何時進行 super 呼叫。

Mixins 也可以將響應式屬性樣式和 API 新增至子類別化的元素。

以下範例中的 mixin 會將 highlight 響應式屬性新增至元素和 renderHighlight() 方法,使用者可以呼叫該方法來包裝一些內容。當設定 highlight 屬性/屬性時,包裝的內容會以黃色樣式顯示。

請注意,在上述範例中,mixin 的使用者應從其 render() 方法呼叫 renderHighlight() 方法,並注意將 mixin 定義的 static styles 新增至子類別樣式。mixin 與使用者之間此合約的性質取決於 mixin 定義,且應由 mixin 作者記錄。

在 TypeScript 中撰寫 LitElement mixins 時,有幾個細節需要注意。

您應該將 superClass 引數限制為您預期使用者要擴充的類別型別(如果有的話)。這可以使用通用 Constructor 協助程式型別來完成,如下所示

上述範例確保傳遞給 mixin 的類別是從 LitElement 擴充而來,因此您的 mixin 可以依賴 Lit 提供的回呼和其他 API。

雖然 TypeScript 基本上支援推斷使用 mixin 模式產生的子類別的傳回型別,但它有一個嚴重的限制,即推斷的類別不得包含具有 privateprotected 存取修飾詞的成員。

由於 LitElement 本身確實具有私有和受保護的成員,因此預設情況下,當傳回擴充 LitElement 的類別時,TypeScript 會顯示錯誤「匯出的類別表達式的屬性 '...' 不得為私有或受保護。」

有兩種解決方法,都涉及將 mixin 函式的傳回型別轉換,以避免上述錯誤。

當 mixin 未新增新的 public/protected API 時

「當 mixin 未新增新的 public/protected API 時」的永久連結

如果您的 mixin 僅覆寫 LitElement 方法或屬性,且未新增任何自己的新 API,您可以簡單地將產生的類別轉換為傳入的父類別型別 T

當 mixin 新增新的 public/protected API 時

「當 mixin 新增新的 public/protected API 時」的永久連結

如果您的 mixin 確實新增了新的受保護或公用 API,而您需要使用者能夠在其類別上使用,您需要與實作分開定義 mixin 的介面,並將傳回型別轉換為 mixin 介面和父類別型別的交集

由於 TypeScript 型別系統的限制,裝飾器(例如 @property())必須套用至類別宣告陳述式,而不是類別表達式。

實際上,這表示 TypeScript 中的 mixins 需要宣告一個類別,然後傳回它,而不是直接從箭頭函式傳回類別表達式。

支援

不支援