📱

[Nuxt3] レスポンシブなLayoutsを画面幅に応じてダイナミックに変更

2023/11/19に公開

モバイル時とPC時とで Nuxt の layouts をダイナミックに切り替えたい時のメモ。
(もっとよい方法あったら教えてください🙇‍♀️)

まずは layouts ディレクトリに mobile.vuedesktop.vue を用意。

次に、responsive という middleware を作成。
ここでは、vueuseuseWindowSize を使用して、画面のwidthの値を判定し、setPageLayout() で、先ほど用意したレイアウトをセット。

/middleware/responsive.ts

import { useWindowSize } from '@vueuse/core';

export default defineNuxtRouteMiddleware(async (to, from) => {
  const { width } = useWindowSize();

  if (process.client) {

    if (width.value < 640) {
      setPageLayout('mobile')
    } else {
      setPageLayout('desktop')
    }
  }
})

最後に、レイアウトを動的に切り替えたい page コンポーネントの <script lang="ts" setup>内にこれを記述。

import { useWindowSize } from '@vueuse/core';
const { width } = useWindowSize();

const layoutName = computed(() => {
  if (width.value < 640) {
    return 'mobile'
  } else {
    return 'desktop'
  }
})

watch(layoutName, (newLayoutName, oldLayoutName) => {
  if (newLayoutName === oldLayoutName) return
  setPageLayout(layoutName.value)
})

definePageMeta({
  middleware: 'responsive'
})

definePageMetaでミドルウェアresponsiveを指定しているこのページではアクセス時の画面の幅によってレイアウトが1度設定され、それ以降は画面幅の変更に応じてリアクティブにレイアウトがセットされます。

Discussion