KUBIO/DEV

Nuxt.jsでClient側でしか使えないコンポーネントを使う

March 26, 2021

Nuxt.jsを勉強中です。

ざっくりvue-grid-layoutを使おうとしたら document is not defined とエラーになりました。 色々試してみて結局動いてないですが、備忘録的にメモしておきます。

エラーになったコード

props省略していますが、エラーになるコードは以下のような感じでした。

<template>
    <grid-layout
      ...
    >
      <grid-item
        v-for="item in layout"
        ...
      >
        {{ item.i }}
      </grid-item>
    </grid-layout>
</template>

<script lang="ts">
import { defineComponent } from '@vue/composition-api'
import { GridLayout, GridItem } from 'vue-grid-layout'

export default defineComponent({
  components: {
    GridLayout,
    GridItem,
  },
  // ...
})
</script>

対策

SSRの際には(window.)documentを参照できないので、クライアント側でのみレンダリングされるように設定する必要があります。

ドキュメントはこちら

具体的に行ったことは以下です。

  1. pluginを利用して、GridLayout,GridItemをグローバルコンポーネントで使えるようにする
  2. nuxt.config.jsでpluginを指定する
  3. <client-only />タグを使う

pluginを利用して、GridLayout,GridItemをグローバルコンポーネントで使えるようにする

pluginsディレクトリにファイルを作成します。(ここではclient-only-components.tsとしました)

import Vue from 'vue';
import { GridLayout, GridItem } from 'vue-grid-layout';

Vue.component('grid-layout', GridLayout);
Vue.component('grid-item', GridItem);

nuxt.config.jsでpluginを指定する

↑で作成したpluginファイルを読み込むために、configファイル内に記述します。 このときに mode: 'client' を指定します。 (ssr: falseでも動きますが、次のメジャーバージョンで非推奨になるようです)

{
    ...
    plugins: [
        ...
        { src: '~/plugins/client-only-components.ts', mode: 'client' },
    ],
    ...
}

<client-only />タグを使う

最終的に修正してこんな感じになりました。

<template>
    <client-only placeholder="Loading...">
        <grid-layout
        ...
        >
        <grid-item
            v-for="item in layout"
            ...
        >
            {{ item.i }}
        </grid-item>
        </grid-layout>
    </client-only>
</template>

<script lang="ts">
import { defineComponent } from '@vue/composition-api'

export default defineComponent({
  // ...
})
</script>

ここまでで document is not definedは出なくなり、コンポーネントが表示されるようになりました。

ただ、次は Unknown custom element: <grid-layout> というようなエラーが出てしまい、pluginsで登録したコンポーネントが認識されないため、今度はこのあたりを調べてメモを更新したいと思います。 うまくいかなったからVue.draggableを使うようにしようかな。。


なんちゃってぷろぐらまーから脱出したい

Written by kubio

© 2022 kubio.dev, Built with Gatsby