LoginSignup
55
44

More than 5 years have passed since last update.

Vue.jsでアプリケーションを開発するときによくある質問集

Last updated at Posted at 2018-07-10

概要

Single Page Applicationを実装するにあたって、気になることの質問・回答集。
ここで言う「Single Page Application」とは、画面遷移(リロード)をせず、1ページ内で
ajaxなどを使用してページ遷移(のような動き)を実装しているものを指します。
また、Vue.jsを使用して実装することを想定しています。
※随時更新していきます。

FAQ

Google Analyticsの測定はできるの?

可能です。
vue-routerでURLを切り替える際に、手動でGA側にページ遷移を通知することで測定されます。
(ブラウザバックではページカウントが増えません)

任意のイベントを通知することも可能ですが、懸念点としては下記が挙げられます(未検証)

  • GAタグ以外で、手動でページ遷移を通知する方法がない計測タグは対応できない
  • Google Tag Managerを使ってページごとに任意の処理を行いたい場合、対応できない可能性がある

参考

https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications
http://sys1yagi.hatenablog.com/entry/2016/11/30/233414

Googleにちゃんとindexされるの?

sitemap.xmlを設置してSearch Consoleで登録すればindexされます。
また、indexされたページもtitleやmeta情報などが反映されており、
Google側でjsが実行された状態でindexされます。

sitemap.xmlの自動生成ツールは使えるの?

使えません。
sitemap.xmlを自動生成するツールは多数Web上にありますが、
SPAに対応してるものはありませんでした。

例:
http://www.sitemapxml.jp

なので、SPAの場合においては、sitemap.xmlを手動作成する必要があります。

ページのURLを自由にカスタマイズできるの?

できます。
Vue.jsがもつvue-routerというモジュールがあり、ページURLと使用するモジュールを紐付けることができます。

URLに動的なパラメータを持たせることも可能です。
下記のページで商品URLの例を確認することができます
ただし、対応する場合はサーバー側でリライトモジュールの設定が必要です。

任意のパラメータを付与させることはできるの?

できます。
vue-routerではパラメータを下記の記載で取得可能です

code
{{ $route.query.name}}

参考:動的ルートマッチング
https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html#%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%E5%A4%89%E6%9B%B4%E3%81%AE%E6%A4%9C%E7%9F%A5

効果測定タグをページ毎に出し分けできるの?

できます。
ただし、ページ遷移をした時点でHTMLの評価は行われるようなので、
Vue.jsのif構文で表示制御をする必要があります。
コンバージョンなどについては当記事内の
「ブラウザバックで戻ったときにコンバージョンタグが複数回カウントされたりしないの?」
の回答を参考のこと

title/metaをページ毎にカスタマイズできるの?

Vue.jsのプラグインである「Vue-Meta」を利用することで実現できます。

Vue-Meta
https://github.com/declandewet/vue-meta#recognized-metainfo-properties

このプラグインでは下記のことが可能です。

  • titleをページ毎に書き換える
  • metaタグ(keywords、description、OGPタグなど)をページ毎に設定する
  • 任意のCSSファイル・javascriptファイルを読み込む
  • nosriptタグを埋める
  • html/bodyに属性を指定する

ブラウザバックで戻ったときにコンバージョンタグが複数回カウントされたりしないの?

実装で回避することができます。
以下のような処理順で行うことで、重複カウントは防げます。
(下記は処理完了ページの例)

※処理完了ページの例
1)ページアクセス
2)APIにてセッションチェック
3)2がOKであれば、完了ページ表示フラグを立てる
4)コンバージョン用のHTMLが出力される

ブラウザバックでアクセスされた場合、2のチェックでエラーになるため、
3以降が行われることなく、エラーページが表示されます。
Vue.js内にHTMLとして普通に記載していると、セッションチェックが終わる前にHTMLを評価してしまうので、
出力フラグを用意し、そのフラグによって出力制御をすることで実現可能です。

各ページのアクセスログって残るの?

残りません。
Single Page Applicationはすべてクライアント側でHTMLの描画を行うので、サーバー側にログは残りません。
ただし、APIを呼び出したログは残ります。
SPA側で「ページ切り替えを行った」ということは検知できるので、その際にログ記録用のAPIに
URL情報を付与して送るなどしておけば、アクセスログを取ることは可能です。

例)
https://~.co.jp/api/accesslog.asp?url=/pd/cosme/test001

ログ記録用APIをわざわざ呼ぶと、APIコール1回分がコストになるので、セッション確認APIに
付与するようにするなどすればより良いです。

そもそもSPAって早いの?

処理自体は変わっておらず、その処理をクライアント側で行うか、サーバー側で
行うかだけの違いなので、処理速度はクライアント側のPCスペックや通信環境に依存します。
SPAでは初回ロード時に必要なjavascriptファイル・CSSファイルはダウンロードされるため、
2ページ目以降の表示は早くなります。また、ヘッダー・フッターなど
共通の部分は最初のページのみでロードされるので、2ページ目以降は少し早くなります。

ただし、SPAではHTMLの構築をすべてjavascriptで行い、ページ遷移がないため、
メモリリークが発生するリスクがあります。
(構築されたHTML情報はメモリに展開されるため)
そのため、場合によっては任意のページでリフレッシュする方が良い場合もあります。
これは状況によるのでサイト毎に考えてください。

SPAで多言語対応ってどうやるの?

Vue.jsのi18nプラグインで対応可能です。
https://qiita.com/_upto_me_/items/6d76dcd2d2c09b1bcb88

手順は以下の通り。

1)i18nプラグインをインストール
2)Vue.jsインスタンス生成時に多言語設定を追加
3)初期値のlocaleを設定
4)JSON形式のmessageファイルを作成
5)HTML内にmessage埋め込み
6)言語切替処理を実装

messageファイルは下記のような形式で作ります。

message.json
{
    "ja": {
      "message": {
        "title": "タイトル",
        "dashbord": "ダッシュボード",
        "subtitle": "ここがサブタイトルになります"
      }
    },
    "en": {
      "message": {
        "title": "title",
        "dashbord": "Dashboard",
        "subtitle": "sub title"
      }
    },
    "han": {
      "message": {
        "title": "標題",
        "dashbord": "儀表盤",
        "subtitle": "副標題"
      }
    }
  }

言語毎にjsonファイルを分けることも可能です。
また、HTML内の記載はこうなります。

html
<h1>{{$t("message.dashbord")}}</h1>

手順の3で設定したlocaleを「jp」や「en」に変更することで、
message.jsonに定義された言語に変わります。
{{$t("message.dashbord")}}の形式で記載されてない箇所は変わりません。

サンプル
http://spa-sample.ivp.co.jp/entry1
(ページ最上部の「ダッシュボード」が変わります)

ページスクロールした位置って記憶してるの?

記憶してます。下記のような動作になります。

1)検索結果ページでページ下部までページスクロール
2)別ページへ遷移
3)ブラウザバックで戻る
4)ページ下部で表示される

また、ブラウザバックではなく、リンクで戻った場合はページ最上部に行きます。

1)検索結果ページでページ下部までページスクロール
2)別ページへ遷移
3)リンクで商品一覧に戻る
4)ページ最上部で表示される

セキュリティでCSRF対策はどのようにすればよいか?

基本的にはサーバーサイドで制御するときと同じです。

1)入力確認画面でトークンを発行する
2)完了画面で1で発行したトークンが生きてることを確認する
3)2がOKであれば登録処理を行い、1のトークンを無効化する

この内容で完了画面への直接アクセス(CSRF)は防げます。
確認画面でのトークン発行は「登録完了」Buttonを押下したタイミングで発行します。
なので、確認→完了のあたりの処理順は下記のようになります。

1)確認画面表示
2)完了画面へ進むボタンクリック
3)トークン発行APIをコール(この時点ではURLは確認画面のまま)
4)完了画面へ遷移
5)登録APIをコール
6)3のトークンが無効化
7)直接完了画面にアクセスしてもトークンがないのでエラーになる

参考情報として、
Laravel(PHPフレームワーク)では、サーバ側でCSRFトークンを発行する形で対応しているようです。
http://blog.asial.co.jp/1496

sitemap.xmlは設置できるの?

設置可能です。

ただし、vue-cliを使ってドメイン直下にファイルを置く場合には、
vue-routerでのルーティング設定か、webpackの設定調整が必要です。
上記サイトではwebpackの設定を調整したので、
staticフォルダ以下に配置しています。

拡張子の制限はないの?

ありません。

faviconを設置したいんだけどこに置けばいいの?

sitemap.xmlや画像フォルダと同じ場所におけばOKです。

httpステータスコードは制御できるの?

できません。
SPAの場合は大本になってるファイルがあり、その中で仮想的にHTMLを構築するため、
存在しないページURLでアクセスされても、200が返却されます。
200が返却された後、ページ表示処理で404のような表示をすることは可能ですが、
httpステータスコード自体を404にすることは不可能です。

ファイル更新したときにキャッシュはどう処理されるの?

色んなアプローチがあると思いますが、Vue.jsではWebPackという技術を使用することで回避しています。
Vue.jsには、vue-cliという開発するためのツールや設定がまとまったものがあるのですが、
その中にwebpackの設定が同梱されています。

vue-cli
https://jp.vuejs.org/2015/12/28/vue-cli/

vue-cliに含まれてるwebpackの設定では、複数のjsファイルやcssファイルを
結合して出力する際、ソースの内容からハッシュ値を生成しファイル名に付与します。

たとえば、

adbeebb4-c790-9c75-6a9b-93d750adb3f2.png

この状態からvue.jsで管理されているhtmlに修正をいれてbuildしなおすと

てst.png

こうなります。
変更が入っていないファイルはそのまま、で変更が入っているファイルはハッシュ値が変わっています。
これでキャッシュされることはありません。

ただし、これはwebpackで管理されているファイルだけなので、webpackの管理外に
なっているファイルは、ハッシュ値の付与がされないので、キャッシュの問題が発生します。
完全に回避しようとすると全てをwebpack管理する必要がありますが、
ルーティングに関するjsファイルは標準でwebpack管理されているので、
ページ遷移できないなどのリスクは少ないのでは・・・・と考えています。

その他

質問などあればコメントに書いていただければと思います!
判明したものから随時アップデートしていきます!

55
44
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
44