04 使用 slot 替換 mixin
目標
在第三篇文章中,我們使用 mixin 來抽離了注入 toggle
依賴項的公共邏輯。在 react 中,類似的需求是通過 HOC 的方式來解決的,但是仔細想想的話,react 在早些的版本也是支援 mixin 特性的,只不過後來將它標註為了 deprecated。
mixin 雖然作為分發可複用功能的常用手段,但是它是一把雙刃劍,除了它所帶來的便利性之外,它還有以下缺點:
- 混入的 mixin 可能包含隱式的依賴項,這在某些情況下可能不是呼叫者所期望的
- 多個 mixin 可能會造成命名衝突問題,且混入結果取決於混入順序
- 使用不當容易使專案的複雜度呈現滾雪球式的增長
所以是否有除了 mixin 以外的替代方案呢?答案當時也是有的,那就是使用 vue 中提供的作用域插槽特性。
實現
這裡關於作用域插槽的知識同樣不贅述了,不熟悉的讀者可以去官方文件瞭解。我們可以在 toggle
元件模板中的 slot
標籤上將所有與其上下文相關的方法及屬性傳遞給它,如下:
<div class="toggle">
<slot :status="status" :toggle="toggle"></slot>
</div>
複製程式碼
這樣,我們可以通過 slot-scope 特性將這些方法和屬性取出來,如下:
<template slot-scope="{status, toggle}">
<custom-button :on="status.on" :toggle="toggle"></custom-button>
<custom-status-indicator :on="status.on"></custom-status-indicator>
</template>
複製程式碼
當然,相比上一篇文章,我們需要對 custom-button
和 custom-status-indicator
元件做一些簡單的更改,只需要將混入 mixin 的邏輯去掉,並分別宣告相應的 props 屬性即可。
成果
通過作用域插槽,我們有效地避免了第三方元件由於混入 toggleMixin 而可能造成的命名衝突以及隱式依賴等問題。
你可以下面的連結來看看這個元件的實現程式碼以及演示:
總結
mixin 雖好,但是一定不要濫用,作為元件開發者,可以享受它帶來的便利性,但是它對於元件呼叫者來說,可能會造成一些不可預料的問題,通過作用域插槽,我們可以將這種問題發生的程度降到最小,同時解決 mixin 需要解決的問題。