東京都 新型コロナウイルス感染症対策サイトを読む その3
続きをやっていく
前回みたいに順番に見ていってもいいけど、特に気になる箇所がないコンポーネントもあるので
適当にソースを眺めて気になった記述の部分を重点的に見ていくことにする
i18nタグ(コンポーネント)
pages/about.vue
に以下のような部分がある
<i18n
tag="p"
path="Google Analyticsによる情報送信を回避する場合は、Google がサポートする{addon}をご利用ください。"
>
<template v-slot:addon>
<external-link
:url="$t('https://tools.google.com/dlpage/gaoptout?hl=ja')"
:icon-size="16"
>
{{ $t('測定を無効にするブラウザ アドオン') }}
</external-link>
</template>
</i18n>
これはVue I18nのスロット構文という機能らしい
tag="p"
でPタグを生成するpath="Google〜〜〜"
はI18nのキーでassets/locales
で定義されている各言語のテキストが埋め込まれる<template v-slot:addon> 〜 </template>
で作成されるHTMLがi18n
コンポーネントのpath内にある{addon}
に展開される
ここでもう一つ気になるのが external-link
という子コンポーネントに対して、 url
と icon-size
というpropsに加え、 {{ $t('測定を無効にするブラウザ アドオン') }}
という要素も渡しているという点
これはVue.js本体のスロットコンテンツという機能を使っている
渡した {{ $t('測定を無効にするブラウザ アドオン') }}
の部分は、 ExternalLink.vue
で <slot />
の部分に展開されている
Rubyの yield
を思い出した
ExternalLink.vue
の v-icon
は前回説明した通り Vuetify
のコンポーネントで、 mdi-open-in-new
はアイコン名のこと(ちゃんと @mdi/font
パッケージも入ってる)
role属性, scope属性
pages/contacts.vue
にv-bindによってモバイル環境の時だけ role: 'presentation'
という属性が付与される部分がある
<table class="Contacts-Card-Table" v-bind="tableAttrs">〜</table>
また、thタグに scope
という属性が付与されている箇所がある
<th class="text-center" scope="col">
これはHTMLの仕様で、アクセシビリティの向上を目的とした属性らしい
要素に意味付けを行い、役割を与えることで、スクリーンリーダーなどの読み上げソフトでwebサイトの構造を認識できるようになるというもの
ちょっとアクセシビリティについては知識が全くないので、どこかで入門しておこう
なお、この部分の修正が入ったPRはこれで
chromeのスクショの Accessibility
タブは、スタイルシートのタブと同じ場所にある
(スタイルシートのタブしか見たことなかったけど、こんなタブがあったとは)
svgをコンポーネントっぽく扱う
pages/flow.vue
の以下の部分
<fig-cond-sy-dr :class="$style.fig" aria-hidden="true" />
これもコンポーネントか?と思ったら、以下のような読み込みがされていた
import FigCondSyDr from '@/static/flow/cond_sydr.svg'
svg
をコンポーネントっぽく扱ってる!
これは nuxt-svg-loader
というパッケージを使うと実現できるらしい
nuxt.config.ts
の module
で読み込まれている
便利〜
Nuxt.jsはどんなモードで動いて、どんなビルドが行われて、どこへデプロイされているのか
今更だけど、やっぱアプリが最終的にどこで動いているのか、そのためにどう作られているのかは知っておきたいので見ていく
nuxt.config.ts
を見るとmode: 'universal'
となっているので、SSRによるレンダリングがおこなわれているpackage.json
のデプロイ周りのコマンドを見るとnuxt-ts generate
されているnuxt.config.ts
を見ると、generate
で動的にルーティングが追加されている- Nuxt.jsは
generate
を行うとpages配下に置いた.vueファイルを静的なコンテンツとして出力してくれる - しかし、動的なルーティングは全て無視されてしまう(コロナ対策サイトだと、pages/cards/XXXがそれに当たる)
- Nuxt.jsは
以上から、ページを generate
で生成し、動的なルーティングは nuxt.config.ts
で追加して作成
配信されたHTMLはユーザーのブラウザ上でSPAとして動作している
デプロイはNetlifyにされていて、静的なサイトとして動作している
という感じだろうか
mode
が universal
だとSSRを使う設定らしいが、サーバーで動いている他のアプリもなさそうだし、どう見てもSSRは使ってないように見えるんだけど
この記事を見ると、 nuxt.config.ts
の generate
で動的なルーティングを設定していること自体がSSRである。という印象を受けた
SSRするならRailsみたいにアクセスに応じて動的にHTMLを生成する何かがサーバーに必要だと思っていたけど、こういう形のSSRもあるということか(確かにSSRと言えばSSRだ)
generate
を使ってSPAにしつつ、あらかじめ動的なルーティングでのHTMLもSSRっぽく生成しておけるから、SSR
ではなく、万能ないいとこ取り的な意味で universal
という表記なのか(そう意図しているかはわからないけど)
ちょっと謎が解けた感じ