💭

Svelteのstoreを使って画面幅を一括管理

2024/09/28に公開

画面幅によって要素の出し分けだったり、処理を分けたいときにコンポーネントごとに定義するのが面倒だったときに使った方法。

まずはconst.js等にブレイクポイントとなる横幅の値を定義。

src/const.js
export const breakPointWidth = 640

次にsrc/store.jsに管理したい横幅を定義する

src/store.js
import { writable } from 'svelte/store';

export const commonWidth = writable(0);

これで横幅をコンポーネントで定義して書き込む準備が出来たので、次は実際に画面幅を取得して書き込む処理を書きます。
+layout.svelteを使うと+page.svelteで呼び出すことになるので+layout.svelteに書きます。

+layout.svelte
<script>
	import {commonWidth} from "../store.js"

	let innerWidth

	$: commonWidth.set(innerWidth);
</script>

<svelte:window bind:innerWidth />

store.jsに定義したcommonWidthを呼び出し、innerWidthcommonWidthにセットします。
<svelte:window />を使うことで横幅が可変するたびにinnerWidthにbindされてそれをcommonWidthにsetする、といった感じです。

あとは+page.svelteで呼び出して、実際に出し分け等をしていきます。

+page.svelte
<script>
	import {commonWidth} from "../store.js"
  import {breakPointWidth} from "../const.js"

  // クリックイベントを画面幅によって変更する。
  function ClickEvent() {
    $commonWidth > breakPointWidth ? LargeEvent() : SmallEvent()
  }

  function LargeEvent () {
    console.log("Large")
  }

  function SmallEvent () {
    console.log("Small")
  }
</script>

<section>
		{#if $commonWidth > breakPointWidth}
			<p>Large</p>
		{:else}
			<p>Small</p>
		{/if}

    <button on:click={ClickEvent}>
</section>

これでどのページコンポーネントでも

*.svelte
	import {commonWidth} from "../store.js"
  import {breakPointWidth} from "../const.js"

を呼び出すだけで使えてスッキリすることが出来ました。
状態管理系のモジュール使えばもっと簡単にできそうではある。。。

ご覧いただきありがとうございました!

Discussion