vue-slickを使用した場合のエラー
複数画像のスライド表示を簡単に実装できるJavascriptのプラグインであるslick.js。
これをVueやNuxtに実装する場合はvue-slickをインストールしてimportすれば簡単に実装できます。
ただここでNuxtに実装する場合は注意が必要です。
無邪気に
import VueSlick from 'vue-slick'
なんてしてしまうと、
window is not defined
のようなエラーが出てしまいます。
Vue.jsではこのようなエラーが出ることはないのになんで...と思ってしまうのですが、
エラーの原因はNuxt.jsではお馴染みのSSR(サーバサイドレンダリング)でDOM要素を操作しようとしていることに起因します。
このような場合、SSRの段階でimportしてしまったらその時点でエラーが発生してしまいます。
エラーの解消法
解消法1
ポイントとしては、SSRで読みこんではいけないので、「process.browser」の時にimportする必要があります。
記述すると以下のようなコードになります。
export default { components: { Slick: () => process.browser ? import('vue-slick') : null, }, }
components内にもimportは書けるのです。
あとはtemplate内に
<client-only> <slick> ・ ・ ・ </slick> </client-only>
のように記述すれば、クライアント側で読み込まれることになるためにエラーが発生しません。
解消法2
vue-slickをimportしたpluginsファイルを用意し、client側で読み込ませる方法もあります。
まずは以下のようにvue-slick.jsというpluginsファイルを作成します。
plugins/vue-slick.js
import Vue from 'vue' import VueSlick from 'vue-slick' Vue.use(VueSlick)
次にこれをnuxt.config.jsで読み込ませる設定を入れればOKです。
「mode: 'client'」と入れることで、クライアント側で読み込ませることができます。
nuxt.config.js
const config = { plugins: [ { src: '~/plugins/vue-slick', mode: 'client' }, ], }
これもtemplate内では
<client-only> <slick> ・ ・ ・ </slick> </client-only>
のようにクライアント側で読み込ませるようにしましょう。
注意点ですが、この方法では「Vue.use(VueSlick)」とプラグインですることで、どこからでも呼び出せる状態になっています。
改めて使用したいコンポーネント内でimportをしないように注意してください。
Nuxtでは同様のエラーが発生するプラグインが多い
今回はvue-slickについてお話しましたが、他にも同様のエラーが発生するプラグインは多いです。
「window is not defined」や「Element is not defined」などのエラーが発生した場合は、DOMがない状態でDOM操作をしていないかを疑いましょう。
また、client-onlyで読み込む要素はSSRでは読まれないため、SEOに必要な要素は入れないようにしましょう。(どうしても入れなくてはいけないケースは多いと思いますが)