📘
シングルトンパターンを利用してトーストの複数表示を行う
はじめに
トーストを複数表示するためにシングルトンパターンを利用したので、備忘録としてまとめます。
Vue-Toastificationを使用してトーストを表示する
弊社ではトーストの表示にVue-Toastificationというライブラリを使用しています。
Vue-Toastificationとは
トーストを簡単に実装できるライブラリです。
vueと名前についていますが、Reactでも使用できるようです。
特徴
- TypeScriptをサポートしている
- トーストの表示や動作を簡単にカスタマイズできる
- 表示の残時間をいい感じに表示、ホバー時には一時停止できる
実装例(シングルトンパターン利用しない)
タイトルやテキストを渡して、動的に変化するようにしたかったので、下記のように実装してみました。
export const toast = (props: {
title: string
text: string
}) => {
const pluginOptions = {
maxToasts: 10,
}
const toast = createToastInterface(pluginOptions)
const content = {
component: SToaster, // カスタマイズしたコンポーネントをセットする
props: {
title: props.title,
text: props.text,
},
}
toast(content, {
type: TYPE.SUCCESS,
})
}
ところが、createToastInterface
が実行されるたびにインスタンスを生成してしまうため、新たに作成したトーストが元のトーストに被って表示されてしまいます。
そこで、シングルトンパターンを用いた実装を行うことにしました。
シングルトンパターンとは
- デザインパターンのひとつ
- クラスのインスタンスが1つしか生成されないことを保証する
シングルトンパターンを用いる簡単な実装例
まずはシングルトンパターンを利用する簡単な例をご紹介します。
class MySingleton {
private static instance: MySingleton
// ポイント1: コンストラクタをprivateにする
private constructor (){}
// ポイント2: インスタンスを取得するためのstaticメソッドを作成する
static getInstance() {
if (MySingleton.instance) {
return MySingleton.instance
}
MySingleton.instance = new MySingleton()
return MySingleton.instance
}
}
const instance1 = MySingleton.getInstance()
const instance2 = MySingleton.getInstance()
console.log(instance1 === instance2) // True
実装のポイント💡
シングルトンパターン実装のポイントは2点です!
-
コンストラクタをprivateにする
クラス外でインスタンスの生成が行えないように、コンストラクタをprivateに設定します。private constructor (){}
-
インスタンスを取得するためのstaticメソッドを作成する
インスタンスの有無を確認し、インスタンスが存在しない場合のみ、インスタンスの生成を行います。static getInstance() { if (MySingleton.instance) { return MySingleton.instance } MySingleton.instance = new MySingleton() return MySingleton.instance }
シングルトンパターンを用いたVue-Toastificationの実装
クラス外からインスタンスを取得するためのstaticメソッドを直接使用しない点が異なりますが、上記の実装例とポイントは同じです。
vueToastification.ts
class Toastification {
private static toastInterface: Toastification
toast
// ポイント1: コンストラクタをprivateにする
private constructor() {
const pluginOptions = {
maxToasts: 10,
}
this.toast = createToastInterface(pluginOptions)
}
// ポイント2: インスタンスを取得するためのstaticメソッドを作成する
private static getInterface() {
if (Toastification.toastInterface) return this.toastInterface
Toastification.toastInterface = new Toastification()
return Toastification.toastInterface
}
static toast = (props: {title: string, text: string}) => {
const toastInterface = Toastification.getInterface()
const content = {
component: SToaster, // カスタマイズしたコンポーネントをセットする
props: {
title: props.title,
text: props.text,
},
}
toastInterface.toast(content, {
type: TYPE.SUCCESS,
closeButton: 'button',
})
}
}
export { toast }
index.vue
<script>
import { defineComponent } from '@vue/composition-api'
import { toast } from '~/vueToastification'
export default defineComponent({
setup() {
const onClick = () => {
// toastを呼び出すことで、トーストが表示される
toast({
title: '成功',
text: 'いい調子ですね',
})
}
return { onClick }
},
})
</script>
シングルトンパターンを使用してcreateToastInterface
を一度だけ呼び出すようにしたことで、トーストが複数表示されるようになりました。
おわりに
最後に宣伝ですが、sweeepではエンジニアを募集しています。ご興味のある方は下記リンクよりご応募お待ちしております!
Discussion