Nuxt generate(SSR)で静的なのに動的コンテンツを入れた時に辛いこと
静的が安い!速い!上手い!
そう思いつつ、静的なコンテンツでありAPIベースなコンテンツを作成し始めた。
と思ったら問題発生!
@nuxtjs/proxyが使えない問題
CORSが辛い。
ローカルではCORSをいじる
本番はURLをサーバー側で許可してもらうなど
まだ、いい対策が見つからず
asyncData使えない問題
こんな感じで書いてAPIを取得するが、これがgenerate時しか取得してくれない問題が発生
<script type="ts">
async asyncData({ $axios }) {
const data = await $axios.$get('https://api~')
return {
lists: data
}
}
</script>
これはcreatedを使うことで解決しました。
<script type="ts">
lists: any = []
async created () {
const data = await $axios.$get('https://api~')
this.lists = data
}
</script>
methodsを使うとDOMの不一致になる問題
基本的にプリレンダリング型のSSRだとmethodsを使ったDOM操作はエラーになる。
でもDOM操作したい!!
ということで登場するのが、client-onlyタグ!
<template>
<div>
<client-only>
<list :lists="lists" />
</client-only>
</div>
</template>
そもそもSSRなのにSSR回避するのはどうかと思うが...
APIで取得した値をシャッフルしたいんじゃ!
computedでfor文のシャッフルするとobjectの中身がランダムにされる問題
これは消耗しました。
シャッフルの処理はあっているのに、なぜ他のリストにも影響が出てかつ、
画像とタイトルの不一致が起こるんだ...
そこでmethodsを使うことにSSR、、、
こうすることで初期レンダリングは遅くなるものの、DOMは更新することが可能になります。
<template>
<div>
<client-only>
<list :lists="shuffleList" />
</client-only>
</div>
</template>
<script type="ts">
...
lists: any = []
shuffleList: any = []
async created () {
const data = await $axios.$get('https://api~')
this.lists = data
this.shuffleList = this.shuffle(this.lists)
}
shuffle (list) {
for (let i = list.length - 1; i > 0; i--) {
const r = Math.floor(Math.random() * (i + 1))
const tmp = list[i]
list[i] = list[r]
list[r] = tmp
}
return list
}
</script>
iOS Safariで自動的に電話番号がリンクになるのでDOMが不一致になる問題
これはmeta情報にformat-detectionを入れることで回避することができます。
{ name: 'format-detection', content: 'telephone=no' }
入れないと何も表示されないのでご注意!
まとめ
プリレンダリングSSRは安い!速い!上手い!ということで辛いこともありますが、対応するとメリットが多いと思います!