Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
まだ間に合う「Vue」勉強会資料
Search
株式会社エッグシステム
September 14, 2019
Programming
0
90
まだ間に合う「Vue」勉強会資料
株式会社エッグシステム
September 14, 2019
Tweet
Share
More Decks by 株式会社エッグシステム
See All by 株式会社エッグシステム
株式会社エッグシステム会社紹介資料/採用募集中
egg_system
1
180
Laravelの歩き方 〜Webアーキテクチャを学ぶ〜
egg_system
0
56
押さえておきたい「実践で使うcssのポイント&Emmet紹介」
egg_system
0
41
複業メンバーと行うフルリモート開発の事例紹介
egg_system
0
940
Other Decks in Programming
See All in Programming
「今のプロジェクトいろいろ大変なんですよ、app/services とかもあって……」/After Kaigi on Rails 2024 LT Night
junk0612
5
2.1k
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
Remix on Hono on Cloudflare Workers
yusukebe
1
290
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
230
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
ECS Service Connectのこれまでのアップデートと今後のRoadmapを見てみる
tkikuc
2
250
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
1
290
Click-free releases & the making of a CLI app
oheyadam
2
120
Compose 1.7のTextFieldはPOBox Plusで日本語変換できない
tomoya0x00
0
190
cmp.Or に感動した
otakakot
3
170
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
Featured
See All Featured
How to Ace a Technical Interview
jacobian
276
23k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Bash Introduction
62gerente
608
210k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
Done Done
chrislema
181
16k
Faster Mobile Websites
deanohume
305
30k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Why Our Code Smells
bkeepers
PRO
334
57k
Side Projects
sachag
452
42k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Visualization
eitanlees
145
15k
Transcript
Vue勉強会 今日からなれるVueエンジニア!
プロフィール • 布村武大 • エッグシステムの社員 • コンサルティングエンジニア • 具体的には、以下の仕事をしている ◦
PM及びフルスタックエンジニア ▪ AWS • Docker ▪ Laravel, Rails ▪ Vue, Nuxt ◦ ITコンサルタント
この勉強会の対象 • こんなことを思っている方 ◦ Vueの記事読んでいるけど、意味がわからない ◦ なんとなく、Vueに触っているけど、よくわからない • マニュアルではない、知識を勉強しにきた •
Vueの現場に入ったけど、全然わからない • 現場で、Vueを導入したいけど、どうすればいいの? • SPAとか、JAMstackとか、よくわからないけど、楽しそう
この勉強会で学べること • Vueの導入パターン • Vueの大枠の知識 • Vueを実装する上での癖 • SPAを作る上でのVueのポイント
みなさんの勉強会の目的は なんでしょうか?
Vue学習の難点 • qitaなどに転がっているVueの解説は、node.jsとJavaScriptが混在している ◦ 導入方法によって、 node.jsでも、JavaScriptでも動かせる ◦ 上記の説明がなく、 Vueの解説が始まる ◦
初心者向けの記事は特に、混在しているものが多い • Vueは癖が強いフレームワークになる ◦ 癖により厄介なバグが発生する ◦ この癖にフォーカスした解説は少ない
本日のアジェンダ 1. Vueの設計思想 2. Vueの基本機能 3. コンポーネントの基本 4. 代表的なプラグインの紹介 5.
SPAという選択肢
1. Vueの設計思想
そもそも、Vueとは? • JavaScriptのフレームワーク • コンポーネント指向に対応した言語 • プログレッシブフレームワーク ◦ プロジェクトの規模やフェーズにあわせた使い方ができる ◦
対義語として、フルスタックフレームワーク • Laravelの標準ライブラリになったため、一気に広まった
コンポーネント指向とは • UI / UXをコンポーネント(部品)単位で設計しようという考え方 ◦ 現状は、画面遷移図など、画面単位の設計が多い • コンポーネント指向には、以下のメリットがある ◦
デザインに一貫性を強化 ◦ マークアップの工数削減 • コンポーネント指向においては、画面という単位は存在しない ◦ コンポーネントの集合としての画面はあるが、画面を定義するのは難しい • コンポーネント指向の具体論として、 Atomic Designがある ◦ Object指向でいう「継承」「多態化」「カプセル化」的な定義をした考え方
Vueの導入例 • CDN版を参照する ◦ とりあえず、Vue使う際にオススメ ◦ スクリプトタグで、 Vueを参照するだけで使える • webpackでコンパイルする
◦ やや中規模になってきた段階でオススメ • nuxtの導入 ◦ 多人数でフロントエンドを開発するなら、オススメ • vue-cliによる導入 ◦ 細かいカスタマイズをしながら、開発するならオススメ
2. Vueの基本機能
• Vueは基本的に一つのインスタンスである ◦ 複数のVueインスタンスを生成することは可能だが、バグの元になる • elで指定した要素にVueはマウントする ◦ 1プリケーションに 1Vueのイメージ •
Vueインスタンス内で、パッケージなどを登録する ◦ 規模が大きくなると、 Vueインスタンスが大きくなる ◦ 大きくなってきたタイミングで、 webpackなど別のサービスに切り替えるといい Vueの基本
細かい環境設定などは特に不要で、このコードだけで vueは動作する Vueの基本的なコード <html> <body> <div id="app">{{ msg }}</div> <body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: '#app', data() { return { msg: 'testです。' } } }) </script> </html>
仮想DOM構造について • VueはDOMを描画してくれる ◦ HTMLには、なにも書いていなくてもよい • DOMと同様にVueも階層構造になっている ◦ 1つのVueインスタンスに、複数の子インスタンスを登録できる ◦
bodyタグが1ファイルに1つなのと、同様のイメージ • 1つのVueインスタンスは、1つのDOM構造を持てる ◦ 最終的なHTMLはVueが描画したHTMLになる • Vueのコードがどれだけ増えても、ルートインスタンスは 1つである
TIPS: DOMとは? • Document Object Modelの略 • 要するに、タグのこと ◦ ブラウザは、タグの
1つ1つをObjectとして、読み込んでいる ◦ これにより、CSSスタイルをあてることができる • DOM構造はnodeとelementからなる ◦ 全部のタグはツリー構造になっているということ ◦ タグは自分自身の情報と、親子関係の情報の2つを持っている
bodyタグ内には、divタグ以外、何も書かれていない Vueの仮想DOM構造 <body><div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el:
'#app', template: '<div><vue-header/><div>ルートインスタンス</div><vue-footer/></div>', components: { VueHeader: { template: '<header>ヘッダー</header>' }, VueFooter: { template: '<div>フッター</div>' } } }) </script></body>
<div id=”app”> がなくなり、別のタグになっている Vueにより描画された後のDOM構造 <body> <div><header>ヘッダー</header><div>ルートインスタンス</div><div>フッター</div></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({
el: '#app', template: '<div><vue-header/><div>ルートインスタンス</div><vue-footer/></div>', components: { VueHeader: { template: '<header>ヘッダー</header>' }, VueFooter: { template: '<div>フッター</div>' } } }) </script></body>
jQueryとの違い • Vueは自分自身でDOM構造を持っている ◦ jQueryはあくまでクエリ、 DOM構造自体は持っていない ◦ jQueryは、既存のDOMの書き換えが得意 ◦ 大規模なDOMの書き換えは、jQueryだと厳しい
• 例えるなら、jQueryはポインタで、Vueはオブジェクトになる ◦ そもそも、VueはDOM自体は書き換えない • VueとjQueryは混ぜるな危険 ◦ Vueでは、直接のDOM操作を非推奨にしている
3. コンポーネントの基本
単一ファイルコンポーネント • webpackを用いて、Vueを実装する場合、使う機能になる ◦ 正確には、vue-loaderというwebpackのプラグインの持つ機能である • .vueの拡張子でVueのコンポーネントを定義することができる • html、css、jsを1つのファイルにまとめたもの ◦
まとめることにより、管理が楽になる ◦ スタイルシートを sassなどの言語で書くことができる ▪ webpackの設定は必要 • nodeやtype scriptの記法で、vueを書くことができる
templateがhtml、scriptがjs、styleがcssになる 単一ファイルコンポーネントの実装例 <template> <div><vue-header/><vue-footer/></div> </template> <script> import VueHeader from '~/VueHeader.vue'
import VueFooter from '~/VueFooter.vue' export default { compoents: [VueHeader, VueFooter] } </script> <style></style>
TIPS:nodeの記法について • 単一ファイルコンポーネントになる export defaultやimportはnodeの記法 • exportとimportは対になっている • exportはファイル内で定義したものを出力している •
以下のコードはexport defaultの内容をHogeHoge変数に格納している ◦ import HogeHoge from ‘hogehoge.js’
export default は、単純にimportする値を定義している export importの例 // in test.js export default
{ export: 'test' } // in import.js import test from './test.js' // 上記のコードは以下と同じ test = { export: 'test' }
• コンポーネントは以下のキーを持つ Objectになる • components • props • data •
computed • watch • methods Vueコンポーネントのデータ構造
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を定義 } }
methods, watchの例 export default { data() { return { value:
'初期値', init: true } }, watch: { value() { // 値が変更した際の動作を定義できる this.setInit(this.value !== '初期値') } }, methods: { // メソッドを定義できる setInit(value) { this.init = value } } }
• Vueではpropsで渡された値は変更できない • emitを使い、親のデータを変更する ◦ これにより、親子間のデータ不整合が起きないようにする ◦ 書き方によっては、 propsを直接変更できる ▪
バグになるので、要注意 • emitはイベントを投げている ◦ emitとは、発生の意味 • 親コンポーネントは、イベントに対応するメソッドを定義できる emit / propsによる親子関のデータ連携
porps / emitの実装例 <template> //@updateでchildからupdateイベントを受け取るように設定している <child :data="data" @update="setData" /> </template>
<script> import child from 'child.js' export default { data() { return { data: 'props' } }, methods: { setData(data) { this.data = data } } } </script>
porps / emitの実装例 <template> // clickもイベントになる <input type="button" @click="emitUpdate" />
</template> <script> export default { props: { data: { type: String } }, // $emitでupdateイベントを起こしている methods: { emitUpdate(value) { this.$emit('update', data) } } } </script>
制御構文 • Vueには描画用の制御構文がある • if文としての、v-ifがある ◦ 表示/非表示の切り替えができる ◦ 似たようなもので、 v-showがある
▪ v-showはdisplay: none;を当てる ▪ v-ifはDOM自体を消す • v-forは繰り返しで描画できる ◦ カレンダーや一覧画面などで使える
v-ifの実装例 <template><div> <p v-if="display">表示中</p> // 切り替えボタンで表示/非表示を変更できる <p v-else>非表示</p> // elseも可能
<button @click="switch">切り替え</button> </div></template> <script> export default { data() { return { display: false } }, methods: { switch() { this.display = this.display } } } </script>
v-forの実装例 <template><div> <p v-for="number in numbers" :key=”number”>項目{{ number }}</p> <button
@click="numbers = numbers + 1">追加</button> // 追加ボタンで項目が増える <button @click="numbers = numbers - 1">削除</button> // ロジックも書ける </div></template> <script> export default { data() { return { numbers: 100 } } } </script>
4. 代表的なプラグイン
代表的なプラグイン • Vuex ◦ Vueによるfluxパターンの実装用プラグイン ◦ props / emitの関係が深くなると導入 •
Vue Router ◦ URLからVueのコンポーネントを変更できるようになる ◦ 主として、SPAを作る際に使う • vue-meta ◦ Vue Routerの拡張プラグイン ◦ URLが変更した際に、メタタグも変更する
TIPS:Fluxパターンについて • MVVMなどのパターンには問題があった ◦ Model-ViewModel-View ◦ 1画面に複数ViewModelが欲しい場合がある ◦ 複数のViewModelに依存関係があると、同期などがややこしくなる •
Fluxパターンは以下の構成になる ◦ Action->Dispatcher->Store->View->Action... ◦ Storeがグローバル変数になる ◦ Dispatcherが変更を制御する • Fluxパターンは以下のメリットがある ◦ グローバル変数の変更に DBでいうトランザクションを使えるようになる ◦ Dispatcherから変更ログを終えるようになる
5. SPAという選択肢
SPAとは? • Single Page Applicationの略 • htmlは1枚しかなくても、複数のページを持つ ◦ Vueなどのjsによりページを変更する •
jsで画面遷移するため、UXを向上できる • jsだけで完結するロジックであれば、オフラインでも使用できる ◦ jsやcssをキャッシュさせることでオフラインでも使用可能にする ◦ pwa(Progressive Web Applications)と呼ばれる技術になる
SPAの問題点 • 初期ローディングが遅くなる ◦ 1ページ内に全ページが入っていると考えてもらえばいい ◦ jsの容量は大きくなるため、どうしてもサイトは重くなる • SEO対策に弱い ◦
jsの動作が終わるまで、メタタグが変わらない ◦ メタタグの読み込みはクローラーが行うため、ブラウザとは違う挙動をする
• Server Side Renderingの略 • サーバー側で、jsを動作させてから、htmlを送る • 実現方法として、以下がある ◦ サーバーにnode.jsをインストールし、
Vueをnode.jsで動作させる ◦ nuxt.jsを使い、各URLに対応するhtmlを予め作っておく ◦ ある程度のhtmlはphpなどのプログラムで描画する SSRという解決方法
その他の解決方法 • SEO対策について ◦ FaaS(Function as a Service)を使う ▪ Aws
Lamdaなど ◦ FaaSでクローラからのアクセスかどうかを切り分ける処理を書く ◦ クローラならば、 FaaS内でレスポンスを返す ◦ その他ブラウザならば、 htmlを返す • 初回ローディングについて ◦ Vueのファイルを分割する ◦ 遅延ローディング機能を使う ▪ Promiseにより、ファイルを importする機能が存在する ▪ const Foo = () => import(‘./Foo.vue’)
6. Vueを実装する
Vueを実装してみよう • VueのCDN版をscriptタグで参照する • ハンバーガーメニューを実装してみる ◦ ボタンを押すと、表示されるハンバーガーメニュー • プルダウンを実装してみる ◦
文字列を打ち込むと絞り込めるプルダウン ◦ 自由入力は不可