どうも、Javaしか書けないこじらです。
先日、Vue.jsで開発をしている場合、OGP対策をするためにはただのSPAサイトとして運用することはできず、SSRを導入する必要があることが分かりました。
Nuxt.jsへの移行が終わったら、この辺も今度記事にするつもりです。
と、前置きはこの辺でさっそく本題に入っていきます。
vue-loading-template
この記事はネットに出回っていない情報だけを穴埋めする記事です。Vue.jsにおけるvue-loading-templateの使い方等は省きます。
というか、SPAであれば実装は簡単なので、公式ドキュメントを参照すれば何も困らずに実装が可能です。
(JavascriptとVue.js初心者の私が言っているのでガチです。)
この記事は、Nuxt.jsでvue-loading-templateを書く際の記述を脳死で書けるようにするための記事です。
Vue.jsの時の実装
Vue.jsで開発をしていた時のvue-loading-templateの実装は以下です。
Loading.vueというコンポーネントを作成し、色んなところで使い回していました。
Vue.js版Loading.vue
<template> <div> <div> <div class="loading-spacer"></div> <vue-loading type="spiningDubbles" color="#aaa" :size="{ width: '80px', height: '80px' }" > </vue-loading> </div> </div> </template> <script> import { VueLoading } from 'vue-loading-template' export default { name: 'loading', components: { VueLoading, }, } </script> <style> .fullview { width: 100%; height: 100%; background: #fefefe; position: fixed; top: 0; left: 0; } .loading-spacer { height: 30%; } </style>
Nuxt.jsでやらなきゃいけないこと
Nust.jsでVue.jsとまったく同じ実装をしようとすると、Loading.vueを取り込んでいる画面を直接URLで指定した場合、もしくはリロードを行った場合に以下のようなエラー画面が表示されます。
「document is not defined」だそうです。
このようにエラー画面に遷移してしまう理由は、サーバ側でクライアント側の処理を実行しようとしているからです。
まぁ、vue-loading-template内でDOMに直接アクセスしているんでしょうね。
これはclient-onlyタグで囲っても、no-ssrタグで囲っても解決できる問題ではありません。
じゃあどうすれば良いのかというと、プラグイン化するのが正解のようです。
vue-loading-templateのプラグイン化
プラグインには色々な書き方があるようですね。
私はこの段階でめちゃくちゃ躓きました。
(まぁ最終的にはパスカルケースとスネークケースのミスっていうしょうもないものだったんですが、ドキュメントとして答えがないと初心者には厳しいですよね…)
まずはNuxt.jsプロジェクトにてプラグイン用のjsファイルを作りましょう。
今回はVueLoading.jsというファイル名で作成しました。
VueLoading.js
plugins/VueLoading.js
import Vue from 'vue' import { VueLoading } from 'vue-loading-template' Vue.component('vue-loading', VueLoading)
これをコピペして使ってください。
Vue.componentでコンポーネント化した場合、第1引数として指定している文字列がタグの名前になります。
つまり、上記をコピペした場合、<vue-loading />と書けばこのモジュールを使用できる訳ですね。
ちなみに、このコンポーネントを参照する場合、importとcomponentsの定義は不要になります。
今度はこれをnuxt.config.jsに登録しましょう。
nuxt.config.js
plugins: [ { src: '~/plugins/VueLoading', ssr: false } ],
ssr: falseとすることにより、サーバ側でのレンダリングを抑制します。
(この記述をちゃんと理解するのはすごく難しいと思うので、とりあえずはなんとなくで理解していますw)
Nuxt.js版Loading.vue
<template> <div> <div> <div class="loading-spacer" /> <client-only> <vue-loading type="spiningDubbles" color="#aaa" :size="{ width: '80px', height: '80px' }" /> </client-only> </div> </div> </template> <script> export default { name: 'Loading' } </script> <style> .fullview { width: 100%; height: 100%; background: #fefefe; position: fixed; top: 0; left: 0; } .loading-spacer { height: 30%; } </style>
変わったのはclient-onlyタグが追加されたこと、vue-loading-templateのimport等がなくなったことです。
これで修正内容はすべてです。
こうやってみると大した修正はしてませんね。
私はmounted終了時にフラグを切り替えて、v-ifでスピナーのアニメーションと画面情報を切り替えています。
SPAの場合はクライアントで処理していたものを一部サーバ側に委譲しているので、スピナーのアニメーションが表示されている時間はかなり短くなった気がします。
なんか、頑張ってローディングアニメーション表示させなくても良かった気もするなぁ…
こじらでした
じゃ
コメント