Slide 1

Slide 1 text

Vue勉強会 今日からなれるVueエンジニア!

Slide 2

Slide 2 text

プロフィール ● 布村武大 ● エッグシステムの社員 ● コンサルティングエンジニア ● 具体的には、以下の仕事をしている ○ PM及びフルスタックエンジニア ■ AWS ● Docker ■ Laravel, Rails ■ Vue, Nuxt ○ ITコンサルタント

Slide 3

Slide 3 text

この勉強会の対象 ● こんなことを思っている方 ○ Vueの記事読んでいるけど、意味がわからない ○ なんとなく、Vueに触っているけど、よくわからない ● マニュアルではない、知識を勉強しにきた ● Vueの現場に入ったけど、全然わからない ● 現場で、Vueを導入したいけど、どうすればいいの? ● SPAとか、JAMstackとか、よくわからないけど、楽しそう

Slide 4

Slide 4 text

この勉強会で学べること ● Vueの導入パターン ● Vueの大枠の知識 ● Vueを実装する上での癖 ● SPAを作る上でのVueのポイント

Slide 5

Slide 5 text

みなさんの勉強会の目的は なんでしょうか?

Slide 6

Slide 6 text

Vue学習の難点 ● qitaなどに転がっているVueの解説は、node.jsとJavaScriptが混在している ○ 導入方法によって、 node.jsでも、JavaScriptでも動かせる ○ 上記の説明がなく、 Vueの解説が始まる ○ 初心者向けの記事は特に、混在しているものが多い ● Vueは癖が強いフレームワークになる ○ 癖により厄介なバグが発生する ○ この癖にフォーカスした解説は少ない

Slide 7

Slide 7 text

本日のアジェンダ 1. Vueの設計思想 2. Vueの基本機能 3. コンポーネントの基本 4. 代表的なプラグインの紹介 5. SPAという選択肢

Slide 8

Slide 8 text

1. Vueの設計思想

Slide 9

Slide 9 text

そもそも、Vueとは? ● JavaScriptのフレームワーク ● コンポーネント指向に対応した言語 ● プログレッシブフレームワーク ○ プロジェクトの規模やフェーズにあわせた使い方ができる ○ 対義語として、フルスタックフレームワーク ● Laravelの標準ライブラリになったため、一気に広まった

Slide 10

Slide 10 text

コンポーネント指向とは ● UI / UXをコンポーネント(部品)単位で設計しようという考え方 ○ 現状は、画面遷移図など、画面単位の設計が多い ● コンポーネント指向には、以下のメリットがある ○ デザインに一貫性を強化 ○ マークアップの工数削減 ● コンポーネント指向においては、画面という単位は存在しない ○ コンポーネントの集合としての画面はあるが、画面を定義するのは難しい ● コンポーネント指向の具体論として、 Atomic Designがある ○ Object指向でいう「継承」「多態化」「カプセル化」的な定義をした考え方

Slide 11

Slide 11 text

Vueの導入例 ● CDN版を参照する ○ とりあえず、Vue使う際にオススメ ○ スクリプトタグで、 Vueを参照するだけで使える ● webpackでコンパイルする ○ やや中規模になってきた段階でオススメ ● nuxtの導入 ○ 多人数でフロントエンドを開発するなら、オススメ ● vue-cliによる導入 ○ 細かいカスタマイズをしながら、開発するならオススメ

Slide 12

Slide 12 text

2. Vueの基本機能

Slide 13

Slide 13 text

● Vueは基本的に一つのインスタンスである ○ 複数のVueインスタンスを生成することは可能だが、バグの元になる ● elで指定した要素にVueはマウントする ○ 1プリケーションに 1Vueのイメージ ● Vueインスタンス内で、パッケージなどを登録する ○ 規模が大きくなると、 Vueインスタンスが大きくなる ○ 大きくなってきたタイミングで、 webpackなど別のサービスに切り替えるといい Vueの基本

Slide 14

Slide 14 text

細かい環境設定などは特に不要で、このコードだけで vueは動作する Vueの基本的なコード
{{ msg }}
new Vue({ el: '#app', data() { return { msg: 'testです。' } } })

Slide 15

Slide 15 text

仮想DOM構造について ● VueはDOMを描画してくれる ○ HTMLには、なにも書いていなくてもよい ● DOMと同様にVueも階層構造になっている ○ 1つのVueインスタンスに、複数の子インスタンスを登録できる ○ bodyタグが1ファイルに1つなのと、同様のイメージ ● 1つのVueインスタンスは、1つのDOM構造を持てる ○ 最終的なHTMLはVueが描画したHTMLになる ● Vueのコードがどれだけ増えても、ルートインスタンスは 1つである

Slide 16

Slide 16 text

TIPS: DOMとは? ● Document Object Modelの略 ● 要するに、タグのこと ○ ブラウザは、タグの 1つ1つをObjectとして、読み込んでいる ○ これにより、CSSスタイルをあてることができる ● DOM構造はnodeとelementからなる ○ 全部のタグはツリー構造になっているということ ○ タグは自分自身の情報と、親子関係の情報の2つを持っている

Slide 17

Slide 17 text

bodyタグ内には、divタグ以外、何も書かれていない Vueの仮想DOM構造
new Vue({ el: '#app', template: '<div><vue-header/><div>ルートインスタンス</div><vue-footer/></div>', components: { VueHeader: { template: '<header>ヘッダー</header>' }, VueFooter: { template: '<div>フッター</div>' } } })

Slide 18

Slide 18 text

がなくなり、別のタグになっている Vueにより描画された後のDOM構造
ヘッダー
ルートインスタンス
フッター
 new Vue({ el: '#app',   template: '<div><vue-header/><div>ルートインスタンス</div><vue-footer/></div>', components: { VueHeader: { template: '<header>ヘッダー</header>' }, VueFooter: { template: '<div>フッター</div>' } } })

Slide 19

Slide 19 text

jQueryとの違い ● Vueは自分自身でDOM構造を持っている ○ jQueryはあくまでクエリ、 DOM構造自体は持っていない ○ jQueryは、既存のDOMの書き換えが得意 ○ 大規模なDOMの書き換えは、jQueryだと厳しい ● 例えるなら、jQueryはポインタで、Vueはオブジェクトになる ○ そもそも、VueはDOM自体は書き換えない ● VueとjQueryは混ぜるな危険 ○ Vueでは、直接のDOM操作を非推奨にしている

Slide 20

Slide 20 text

3. コンポーネントの基本

Slide 21

Slide 21 text

単一ファイルコンポーネント ● webpackを用いて、Vueを実装する場合、使う機能になる ○ 正確には、vue-loaderというwebpackのプラグインの持つ機能である ● .vueの拡張子でVueのコンポーネントを定義することができる ● html、css、jsを1つのファイルにまとめたもの ○ まとめることにより、管理が楽になる ○ スタイルシートを sassなどの言語で書くことができる ■ webpackの設定は必要 ● nodeやtype scriptの記法で、vueを書くことができる

Slide 22

Slide 22 text

templateがhtml、scriptがjs、styleがcssになる 単一ファイルコンポーネントの実装例
import VueHeader from '~/VueHeader.vue' import VueFooter from '~/VueFooter.vue' export default { compoents: [VueHeader, VueFooter] }

Slide 23

Slide 23 text

TIPS:nodeの記法について ● 単一ファイルコンポーネントになる export defaultやimportはnodeの記法 ● exportとimportは対になっている ● exportはファイル内で定義したものを出力している ● 以下のコードはexport defaultの内容をHogeHoge変数に格納している ○ import HogeHoge from ‘hogehoge.js’

Slide 24

Slide 24 text

export default は、単純にimportする値を定義している export importの例 // in test.js export default { export: 'test' } // in import.js import test from './test.js' // 上記のコードは以下と同じ test = { export: 'test' }

Slide 25

Slide 25 text

● コンポーネントは以下のキーを持つ Objectになる ● components ● props ● data ● computed ● watch ● methods Vueコンポーネントのデータ構造

Slide 26

Slide 26 text

components, props, data, computed import child from './child.js' export default { components: { child }, // 子コンポーネントを定義 props: { // 親から渡される値を定義 value: { type: String } // 型指定が可能 }, data() { return { data: '初期値' } }, // コンポーネント自体が持つ値 computed: { isInitial() { return this.data === '初期値' } // getterを定義 } }

Slide 27

Slide 27 text

methods, watchの例 export default { data() { return { value: '初期値', init: true } }, watch: { value() { // 値が変更した際の動作を定義できる this.setInit(this.value !== '初期値') } }, methods: { // メソッドを定義できる setInit(value) { this.init = value } } }

Slide 28

Slide 28 text

● Vueではpropsで渡された値は変更できない ● emitを使い、親のデータを変更する ○ これにより、親子間のデータ不整合が起きないようにする ○ 書き方によっては、 propsを直接変更できる ■ バグになるので、要注意 ● emitはイベントを投げている ○ emitとは、発生の意味 ● 親コンポーネントは、イベントに対応するメソッドを定義できる emit / propsによる親子関のデータ連携

Slide 29

Slide 29 text

porps / emitの実装例 //@updateでchildからupdateイベントを受け取るように設定している import child from 'child.js' export default { data() { return { data: 'props' } }, methods: { setData(data) { this.data = data } } }

Slide 30

Slide 30 text

porps / emitの実装例 // clickもイベントになる export default { props: { data: { type: String } }, // $emitでupdateイベントを起こしている methods: { emitUpdate(value) { this.$emit('update', data) } } }

Slide 31

Slide 31 text

制御構文 ● Vueには描画用の制御構文がある ● if文としての、v-ifがある ○ 表示/非表示の切り替えができる ○ 似たようなもので、 v-showがある ■ v-showはdisplay: none;を当てる ■ v-ifはDOM自体を消す ● v-forは繰り返しで描画できる ○ カレンダーや一覧画面などで使える

Slide 32

Slide 32 text

v-ifの実装例

表示中

// 切り替えボタンで表示/非表示を変更できる

非表示

// elseも可能 切り替え
export default { data() { return { display: false } }, methods: { switch() { this.display = this.display } } }

Slide 33

Slide 33 text

v-forの実装例

項目{{ number }}

追加 // 追加ボタンで項目が増える 削除 // ロジックも書ける
export default { data() { return { numbers: 100 } } }

Slide 34

Slide 34 text

4. 代表的なプラグイン

Slide 35

Slide 35 text

代表的なプラグイン ● Vuex ○ Vueによるfluxパターンの実装用プラグイン ○ props / emitの関係が深くなると導入 ● Vue Router ○ URLからVueのコンポーネントを変更できるようになる ○ 主として、SPAを作る際に使う ● vue-meta ○ Vue Routerの拡張プラグイン ○ URLが変更した際に、メタタグも変更する

Slide 36

Slide 36 text

TIPS:Fluxパターンについて ● MVVMなどのパターンには問題があった ○ Model-ViewModel-View ○ 1画面に複数ViewModelが欲しい場合がある ○ 複数のViewModelに依存関係があると、同期などがややこしくなる ● Fluxパターンは以下の構成になる ○ Action->Dispatcher->Store->View->Action... ○ Storeがグローバル変数になる ○ Dispatcherが変更を制御する ● Fluxパターンは以下のメリットがある ○ グローバル変数の変更に DBでいうトランザクションを使えるようになる ○ Dispatcherから変更ログを終えるようになる

Slide 37

Slide 37 text

5. SPAという選択肢

Slide 38

Slide 38 text

SPAとは? ● Single Page Applicationの略 ● htmlは1枚しかなくても、複数のページを持つ ○ Vueなどのjsによりページを変更する ● jsで画面遷移するため、UXを向上できる ● jsだけで完結するロジックであれば、オフラインでも使用できる ○ jsやcssをキャッシュさせることでオフラインでも使用可能にする ○ pwa(Progressive Web Applications)と呼ばれる技術になる

Slide 39

Slide 39 text

SPAの問題点 ● 初期ローディングが遅くなる ○ 1ページ内に全ページが入っていると考えてもらえばいい ○ jsの容量は大きくなるため、どうしてもサイトは重くなる ● SEO対策に弱い ○ jsの動作が終わるまで、メタタグが変わらない ○ メタタグの読み込みはクローラーが行うため、ブラウザとは違う挙動をする

Slide 40

Slide 40 text

● Server Side Renderingの略 ● サーバー側で、jsを動作させてから、htmlを送る ● 実現方法として、以下がある ○ サーバーにnode.jsをインストールし、 Vueをnode.jsで動作させる ○ nuxt.jsを使い、各URLに対応するhtmlを予め作っておく ○ ある程度のhtmlはphpなどのプログラムで描画する SSRという解決方法

Slide 41

Slide 41 text

その他の解決方法 ● SEO対策について ○ FaaS(Function as a Service)を使う ■ Aws Lamdaなど ○ FaaSでクローラからのアクセスかどうかを切り分ける処理を書く ○ クローラならば、 FaaS内でレスポンスを返す ○ その他ブラウザならば、 htmlを返す ● 初回ローディングについて ○ Vueのファイルを分割する ○ 遅延ローディング機能を使う ■ Promiseにより、ファイルを importする機能が存在する ■ const Foo = () => import(‘./Foo.vue’)

Slide 42

Slide 42 text

6. Vueを実装する

Slide 43

Slide 43 text

Vueを実装してみよう ● VueのCDN版をscriptタグで参照する ● ハンバーガーメニューを実装してみる ○ ボタンを押すと、表示されるハンバーガーメニュー ● プルダウンを実装してみる ○ 文字列を打ち込むと絞り込めるプルダウン ○ 自由入力は不可