Skip to main content
前回のVueの基礎を経て
実際にVueを使ってみると、DOMの取得や更新⼿続きが楽になる⼀⽅、
直接JSで書くことに⽐べ、どうやって書くのか考えさせるところがあった
のかなと思います。
その辺りは⼤きく、
・Vue.jsの記述の慣れ (主観)
・何を状態として管理するか (設計)
によるところではないかと思います。
それ以外にも、使い込んでみるとVue.js単体だと設計上やりづらい⼀⾯も
⾒えてきたでしょうし、今回はそれらを補ってくれるプラグインやツール
類を紹介していきます。
→この辺りはReactのような仮想DOM×UIライブラリであるあるなこと?
(余談) Vueを使ったサンプル・事例
Vue Example
Vue公式サイトに掲載された、Vueのサンプル集。
数は少ないが、HTML / CSS / JSタブで確認できます。
https://vuejs.org/v2/examples/
Vue.js Examples
Vueで作った、多様なUIコンポーネントが揃っています。
UIの他、アニメーションやゲームとカテゴリーも豊富。
https://vuejsexamples.com/
made with vue.js
Vueで作られた事例がカテゴライズ。
クオリティもいい具合に仕上がっています。
https://madewithvuejs.com/
Vueの関連ツール
ここからはvue-cliを使って環境を準備します
(参考) vue-cli
 $ npm install -g vue-cli
1. vue-cliをインストールしていない場合は、

以下のコマンドを実⾏(nodeを事前にインストール)
2. 作りたいプロジェクト名を指定すると、

プロジェクト名からVue-Routerの使⽤、Lintツールの使⽤等聞かれます。

それが終わるとプロジェクトディレクトリが作成されます。

あとは、そのディレクトリに移動して`npm run dev`を実⾏。
 $ vue init webpack <プロジェクト名>
 $ cd <プロジェクト名>
 $ npm run dev
状態管理の課題点
Vue.jsは、⼩規模で完結するアプリケーションや機能ならそれ単体で作れ
ます。が、アプリケーションの規模が⼤きくなり、複数コンポーネントで
作って⾏くと、以下のような点から作り⽅が⼤変になってきます。
複数のコンポーネントで状態を共有するケース
(1) 複数のコンポーネントが共通の状態を参照(取得)する
(2) 複数のコンポーネントで共通の状態を更新する
→ Vue単体でやろうとすると、
親に共有する状態を集約し、
(1)は親のコンポーネントから⼦・孫…とpropsを数珠繋ぎ
(2)はカスタムメソッドで孫→⼦→親へと数珠繋ぎ
→ 複数コンポーネントが関連し・⾒通しが悪くなる
→ 数珠繋ぎスパイラル + スパゲティる⼀因にも
つらい。。
そんなとき、
どこでデータを書き換えているのかを
分かりやすくするため、「Vuex」を使います。
Vuex
https://vuex.vuejs.org/ja/
Vuex
Vueの状態管理をサポートしてくれるプラグイン。
FluxやReduxといった状態管理ライブラリに影響を受けてできました。
「ストア」と呼ばれるコンテナに、以下4つがまとめられています。
コンポーネントはストア経由で実⾏
(直接ストアの状態を更新するのはNG、ミューテーションのみが更新可)。
-ステート(state) … アプリケーションの状態を設定
-ゲッター(getter) … 状態(ステート)を参照
-ミューテーション(mutation) … 状態(ステート)を更新
-アクション(action) … ミューテーションのラッパー、呼び出し
Vuexストア
state
(状態)
getter
(参照)
mutation
(更新)
action
(呼び出し)
Vuexのワークフロー
https://vuex.vuejs.org/ja/intro.html
(雑記) Vuex
data(){
return { … }
},
computed: {
xxx(){
return …;
}
},
methods: {
vvv(){
…
}
}
Vueでの管理が複雑化する背景に、「コンポーネント内で⾒た⽬と状態が
密になっている構成」が背景にあると思われます。
皆が参照・更新できるよう、コンポーネント内のデータ・算出プロパティ・
メソッドを⾒た⽬から分離したものがVuexのイメージ。
それはコンポーネント群から解き放たれた「天空の城 ラピ●タ」、
形のない「⾏政」、「国会」?? →むしろ例えなくても良いかも
データ
算出プロパティ
メソッド
Vuexのインストール
 $ npm install vuex --save
1. Vuexのサイトから直接ダウンロード or

以下コマンドでインストール。
2. npmでインストールした場合は、
 JS側で以下のように読み込み、`Vue.use()`で使うことを明⽰化します。
 ※ scriptタグを使っている場合は以下の記述は不要
 import Vue from ' vue'
 import Vuex from 'vuex'
 Vue.use(Vuex)
ストアファイルの作成・組み込み①
vue-cliで作ったものだと、
以下の階層にストアファイルを作ります。
/src/store/index.js
ストアファイルの作成・組み込み②
/src/store/index.jsを以下のように記述します。
new Vuex.Store({})という記述、⾒覚えがありませんか?
Vueインスタンスを作った時の記述と似ているかなと思います。
同じくこの中にオプションを書き⾜していきます。
 import Vue from ‘vue'
 import Vuex from 'vuex'
 Vue.use(Vuex)
 const store = new Vuex.Store({
 })
 export default store
index.js
ストアファイルの作成・組み込み③
/src/main.jsに⾚字のように追記をします。
これにより、VuexストアがVueインスタンスとその中のコンポーネントに
も適⽤されます。
 import Vue from ‘vue'
 import App from './App'
 import router from './router'
 import store from './store/'
 Vue.config.productionTip = false
 new Vue({
  el: '#app',
  store,
  router,
  components: { App },
  template: '<App/>'
 })
main.js
ステート(state)
前述の通りアプリケーションの状態を記述。
前回、data: function(){ … }で状態を記述したが、それのように記述。
違いとしては、stateでは関数でなくオブジェクト形式。
コンポーネントから`this.$store.state.count`でステートを直接参照する
こともできます。
 const store = new Vuex.Store({
  state: {
  count: 0,
  text: 'Hello, Vuex'
  }
 })
https://vuex.vuejs.org/ja/getting-started.html
index.js
ゲッター(getter)
Vuexストアのステートを参照。
前述のように `this.$store.state.count`のように参照もできますが、
ゲッターを介して参照することでVuexの役割を明⽰化することに。
コンポーネントからは`this.$store.getters.count`で参照できます。
 const store = new Vuex.Store({
  state: { … },
  getters: {
  count () {
  return store.state.count
  },
  text () {
  return store.state.text
  }
  }
 })
index.js
https://vuex.vuejs.org/ja/getters.html
ミューテーション(mutation)
Vuexストアのステートを更新。
第⼀引数(state)がステートになっており、第⼆引数に更新したい値。
コンポーネントからは
`this.$store.commit(ʻsetCountʼ, 10 )`で実⾏されます。
 const store = new Vuex.Store({
  …,
  mutations: {
  setCount (state, n) {
  state.count = n
  },
  setText (state, payload) {
  // 複数の値を渡す場合は、第⼆引数(payload)をオブジェクト形式
  state.text = payload.text
  }
  }
 })
https://vuex.vuejs.org/ja/mutations.html
index.js
アクション(action)
Vuexストアのミューテーションをラッパーする。
ミューテーションを使えば良いのではと思われますが、ミューテーション
では⾮同期を含めた処理を書かないようになっています。
アクションでは⾮同期を含めた処理を書けるので、その中でミューテーショ
ンを実⾏します(引数の指定⽅法はミューテーションと同じ)。
`this.$store.dispatch(ʻsetTextʼ, payload )`で実⾏されます。
 const store = new Vuex.Store({
  …,
  actions: {
  setText (context, payload) {
  setTimeout(() => {
  context.commit('setText', payload)
  }, 1000)
  }
  }
 })
index.js
https://vuex.vuejs.org/ja/actions.html
(雑記) Vue Devtools
Vueの状態や要素をインスペクタで確認できます。
Chromeの拡張機能としても公開されています。
https://github.com/vuejs/vue-devtools#vue-devtools
Vue-Router
https://router.vuejs.org/ja/
Vue-Router
いわゆる、「コンテンツの交通整理」。
ブラウザから受け取ったURLに沿って、
然るページを返すことができるプラグイン。
ルーティング設定から、シングルページアプリケーション(SPA)の構築に
活⽤されています。
(雑記) Single Page Application (SPA)
単⼀のWebページのみから構成することで、デスクトップアプリケーショ
ンのようなユーザ体験を提供するWebアプリケーションまたはWebサイト
である。必要なコード(HTML、JavaScript、CSS)は最初にまとめて読み
込むか、ユーザの操作などに応じて動的にサーバと通信し、必要なものだ
け読み込みを⾏う
(by Wikipedia)
Ajaxによって、フロントエンドで部分更新ができるようになり、
それによりページ遷移を⾏うことなくアプリケーションのようなUX体験
ができるようになりました。
→ 対応したコンテンツを表⽰させるためにURLを設定する必要があり、
そこにVue-Routerが使われます。
https://ja.wikipedia.org/wiki/
%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9A%E3%83%BC%E3%82%B8%E3
%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83
%B3
Vue-Routerのインストール
 $ npm install vue-router
1. vue-cliを使っている場合、プロジェクト作成時に選択可能。

最初から準備する場合は、Vue-Routerのサイトから

直接ダウンロード or 以下コマンドでインストール。
2. npmでインストールした場合は、
 JS側で以下のように読み込み、`Vue.use()`で使うことを明⽰化します。
 ※ scriptタグを使っている場合は以下の記述は不要
 import Vue from ' vue'
 import VueRouter from 'vue-router'
 Vue.use(VueRouter)
シングルページアプリケーションを
作ってみよう(簡易版)
ルーティング設定①
vue-cliで作ったものだと、
以下の階層にルーティング設定が記載されています。
/src/router/index.js
ルーティング設定②
ルーティングによって切り替える表⽰領域は、以下のように
<router-view/>
タグを追加します。
URLによってコンテンツを切り替えるには①
/src/components/ディレクトリにAbout.vueファイルを作成し、
以下のように記述をします。
 <template>
  <div>
  <p>Hello, Vue-Router</p>
  </div>
 </template>
 <script>
 export default {
 }
 </script>
 <style>
 </style>
About.vue
URLによってコンテンツを切り替えるには②
ルーティング設定を⾏っている、index.js側に新たにURLを追加します。
 export default new Router({
  routes: [
  {
  path: '/',
  name: 'HelloWorld',
  component: HelloWorld
  },
  {
  path: ‘/about', // /aboutにアクセスされたとき
  component: About // Aboutコンポーネントを使う
  }
  ]
 })
URLによってコンテンツを切り替えるには③
<router-view/>のエリア
URLにハッシュを表⽰させないようにするには①
Vue-Routerはデフォルトでhashモードを使⽤しています。
ハッシュを取り除いたURLで表⽰させるには、historyモードを使⽤します。
※HTML5 History APIとサーバ設定の記述が必要
 export default new Router({
  mode: 'history',
  routes: [
  {
  path: '/',
  name: 'HelloWorld',
  component: HelloWorld
  }
  ]
 })
https://router.vuejs.org/ja/essentials/history-mode.html
https://router.vuejs.org/ja/api/options.html#routes
URLにハッシュを表⽰させないようにするには②
アンカーでURL切り替えを⾏うには
<router-link to=“(遷移先)”>タグを使うとアンカータグ(<a>)に変換。
また、何かの処理をJSで⾏なったのち遷移させたい場合、
`this.$router.push(ʻ(遷移先)ʼ)`をJS内に記述します。
 <template>
  <div>
  <p>Hello, Vue-Router</p>
  <router-link to="/">Top</router-link>
  </div>
 </template>
 <script>
 export default {
 }
 </script>
 <style>
 </style>
About.vue
https://router.vuejs.org/ja/essentials/navigation.html
ページ切り替えにアニメーションさせたい
ここでも<transition>タグを使って、ページ切り替え時に
アニメーションを追加させることができます。
<router-view/>タグを<transition>タグで囲み、
CSS側でトランジション・アニメーションを書きます。
 <template>
  <div id="app">
  <img src="./assets/logo.png">
  <transition name="fade" mode="out-in">
  <router-view/>
  </transition>
  </div>
 </template>
App.vue
https://jp.vuejs.org/v2/guide/transitions.html
https://router.vuejs.org/ja/advanced/transitions.html
(雑記) Vue-Router
前回、コンポーネント(.vue)に関して
「再利⽤可能なパーツの構造・⾒た⽬・振る舞いのセット」
というくくりでお話ししてきました。例えば、ボタン、モーダル、etc…
今回のVue-Routerではページであったりセクションのような形で⽤いら
れ、それの表⽰切り替えを⾏なっています。
再利⽤である・⼩さい粒度という前提条件はなく、モジュール単位として
管理するということで覚えると良いかなと思いました。
なお、後述するNuxtのページ作成においても
.vue形式で管理していくことになります。
例えば、右図の⾚枠をコンポーネントとして管理
したりとか。コンポーネントの粒度は作るものに
よって分かれます。
Nuxt
SPAのメリット・デメリット
SPAに先のようなメリットの⼀⽅、デメリットもあります。
メリット:
- 同⼀ページ内で遷移 → Cookie, localStorageによるページ間の受
け渡し処理が不要
- 部分読み込みによるUX向上(アプリケーションのような体験)
デメリット:
- 初期読み込みのボリューム

(単⼀ページに⽐べ、読み込むアセットサイズが⼤きくなる)
- JSで動的に切り替わるため、SEOのフォローが難

(googlebotでjsレンダリングも対応していると⾔われているが完全
にOKとは⾔いがたい)
→そうした課題に対し、近年サーバサイドレンダリングというワードが
Server Side Rendering (SSR)
HTMLを構築する仕組みがブラウザとサーバで共通のものが⼊ってきてい
て、それを共通のロジックを使って動かす
(Node.js⽇本ユーザーグループ 古川さん)
http://www.publickey1.jp/blog/17/server_side_renderingserver_side_rendering_ng-japan_2017.html
(雑記) Server Side Rendering
SPAだと、
初期表⽰に⽐較的時間がかかる
→ 初期描画前が⽩い画⾯ or ローディング画⾯を⼊れる必要がある
→ 初期描画の処理をサーバ側で⾏ってしまおう
→ 初期描画の処理をクライアントサイド(JS)で書いてるから、

  サーバにもJSのロジックを使おう(Node JS)
Universal Javascript !
(クライアント・サーバで共通のJSロジックを使う)
初期表⽰以降は、SPAで動的に切り替えればいいよね!
これがいわゆる、
SSRのメリット・デメリット
SPAの課題をクリアできる⼀⽅でこんなデメリットも?
メリット:
- 初期描画のパフォーマンス向上
- SEO対策(サーバ側で描画されるため、コンテンツがインデックス)
デメリット:
- Node.jsによるサーバ環境構築
- 実例がそこまで多くないため、ハマったときのリカバー
https://qiita.com/shibukawa/items/184d3101946ec4fa98c1
https://lealog.hateblo.jp/entry/2017/07/10/073926
と、SSRいろいろ書いてしまいましたが
Vueでサーバサイドレンダリングできるフレームワークがあります。
https://nuxtjs.org/
Nuxtのインストール
 $ vue init nuxt-community/starter-template <プロジェクト名>
1. Nuxt公式サイトからzipファイルをダウンロードするか、
 vue-cliでテンプレートをダウンロード。
2. プロジェクト名のディレクトリが作られるので、
 ディレクトリに移動して`npm install`(yarnを使ってる⼈は`yarn`)
 $ cd <プロジェクト名>
 $ npm install (or yarn)
3. 依存パッケージのインストールが完了したら、`npm run dev`
 $ nom run dev
Nuxtで開発環境をカスタマイズ①
 $ npm install —save-dev pug pug-loader
Nuxtにはvue-loaderがあり、sassやpugといったプリプロセッサを導⼊で
きる環境が整っています。
使うときには、パッケージをインストールしlang属性を追加します。
例えば、htmlのテンプレートエンジンであるpugを使うには、
https://ja.nuxtjs.org/faq/pre-processors
.vueファイルの<template>タグにlang=“pug”を追加
 <template lang=“pug”>
 p Hello,
span Vue.js
 // <p>Hello, <span>Vue.js</span></p>
 </template>
Nuxtで開発環境をカスタマイズ②
CSSのプリプロセッサを扱うには、
pugと同様に、使うプリプロセッサとloaderをインストール。
https://ja.nuxtjs.org/faq/pre-processors
.vueファイルの<style>タグにlang=“sass”を追加
 <style lang=“sass”>
 p
  font-size: 16px;
  span
  font-size: 24px;
 </style>
 $ npm install —save-dev node-sass sass-loader
(雑記) Nuxtを使った所感
- サーバサイドレンダリングを扱わなくても、開発環境として使える

(Vue-Router、Vuexがすでに組み込まれている)

- pagesのディレクトリ構造によってルーティングが⾃動設定

- webpack.config.jsに書かずプリプロセッサが使える

- 静的ファイルとしても出⼒可能

- CakePHPとかLaravelのようなサーバサイドフレームワーク

使ったことある⼈なら馴染みのあるディレクトリ構造
ありがとうございました