はじめに
こんにちは、Mottyです。最近Vueを業務で扱うことになったので、関連した項目を書き知るしていこうと思います。
今回はレスポンシブデザインについてです。
複雑なレスポンシブデザイン
レスポンシブデザインは画面のサイズに応じて最適な形にコードを整えるデザインです。これによってスマホやPCのような画面サイズの異なる媒体でもストレスなく閲覧でき、UXが向上することが期待できます。
Script部分
単純に横並び表示を縦にするのであればflex containerのプロパティを変えればよいですが、表示形式がかなり変わるなどの複雑な形になると、コンポーネントもしくはHTMLブロック単位でがらっと切り替えたほうがいいケースもあるかと思います。
windowのサイズが768以下かそれ以上かをbool型で受け取る変数を用意します。
ウインドウサイズの変更を感知し、画面サイズが大きいか否かの情報を常に返し続けるよう、イベントリスナーに登録します。
またtemplateにも反映されるので、変数の値はref()関数で監視します。
<script setup>
import { ref, onMounted} from 'vue';
//screen sizeをbool型で受け取る
let isLargeScreen = ref(window.innerWidth >= 768);
// ウィンドウサイズが変更されるたびに実行される関数
function handleResize() {
isLargeScreen.value = window.innerWidth >= 768;
}
onMounted(() => {
// コンポーネントがマウントされた後、リサイズイベントリスナーを追加
window.addEventListener('resize', handleResize);
});
</script>
template部分
次にtemplate部分の実装です。親側から差し込めるようにslot口を2つ用意します。
2つはそれぞれ表示させたりさせなかったりします。その条件はscreenが閾値より大きいかどうか、です。
<template>
<div>
<div>
<!-- 768px未満の場合、小さいコンテンツスロットを表示 -->
<slot name="small" v-if="!isLargeScreen"></slot>
</div>
<div>
<!-- 768px以上の場合、大きいコンテンツスロットを表示 -->
<slot name="large" v-if="isLargeScreen"></slot>
</div>
</div>
</template>
親コンポーネントでの呼び出し
上記をとし、親側からは以下のように呼び出します。
templateの間に表示させたいコンポーネントをそれぞれ差し込みます。
<template>
<SwitchComponentSystem>
<template #small>
<ComponentA/>
</template>
<template #large>
<ComponentB/>
</template>
</SwitchComponentSystem>
</template>
これによってComponentAとComponentBを切り替えられるようになりました。
終わりに
内部的には2パターンを作って、見せる/見せないを切り替えています。
cssのdisplayプロパティだけでも制御は可能だと思いますが、より汎用的なコンテナとして使いまわすことを期待して作成するに至りました。