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
92
まだ間に合う「Vue」勉強会資料
株式会社エッグシステム
September 14, 2019
Tweet
Share
More Decks by 株式会社エッグシステム
See All by 株式会社エッグシステム
株式会社エッグシステム会社紹介資料/採用募集中
egg_system
1
180
Laravelの歩き方 〜Webアーキテクチャを学ぶ〜
egg_system
0
57
押さえておきたい「実践で使うcssのポイント&Emmet紹介」
egg_system
0
42
複業メンバーと行うフルリモート開発の事例紹介
egg_system
0
1k
Other Decks in Programming
See All in Programming
これが俺の”自分戦略” プロセスを楽しんでいこう! - Developers CAREER Boost 2024
niftycorp
PRO
0
190
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
310
Haze - Real time background blurring
chrisbanes
1
510
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
MCP with Cloudflare Workers
yusukebe
2
220
42 best practices for Symfony, a decade later
tucksaun
1
180
Zoneless Testing
rainerhahnekamp
0
120
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
230
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
120
선언형 UI에서의 상태관리
l2hyunwoo
0
150
モバイルアプリにおける自動テストの導入戦略
ostk0069
0
110
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
300
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
A Philosophy of Restraint
colly
203
16k
For a Future-Friendly Web
brad_frost
175
9.4k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
Faster Mobile Websites
deanohume
305
30k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Navigating Team Friction
lara
183
15k
A Tale of Four Properties
chriscoyier
157
23k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
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タグで参照する • ハンバーガーメニューを実装してみる ◦ ボタンを押すと、表示されるハンバーガーメニュー • プルダウンを実装してみる ◦
文字列を打ち込むと絞り込めるプルダウン ◦ 自由入力は不可