O slideshow foi denunciado.
Seu SlideShare está sendo baixado. ×

はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)

Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Carregando em…3
×

Confira estes a seguir

1 de 51 Anúncio

Mais Conteúdo rRelacionado

Semelhante a はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原) (20)

Mais de 虎の穴 開発室 (20)

Anúncio

Mais recentes (20)

はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)

  1. 1. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. はじめようVue3!
 とらのあなラボのフロントエンドを学ぶ
 
 虎の穴ラボ 藤原 佳顕
 1
  2. 2. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 2 Twitterへのご投稿は、 #とらラボ3 でお願いします! 質問、感想・コメント等 ※ LT内容に関する ご質問はYoutubeコメントにお願いします🙏
  3. 3. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. アジェンダ
 ● 自己紹介
 ● なぜVue(3)か
 ● とらのあなラボでのVue(3)活用
 ● 今回利用する環境について
 ● Vue3の紹介
 ● まとめ
 3
  4. 4. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 自己紹介
 ● 名前:藤原 佳顕
 ● 所属:虎の穴ラボ
 ● やっていること:(Fantia、)新規サービス、社内ツール、ソースレビュー
 ● 好きなもの:RustとかClojureとかDenoとか
 ● 好きなもの2:STG、音ゲー、格ゲー
 4
  5. 5. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. なぜVue3か
 ● 一時期のフレームワークが群雄割拠していた時代に比べて、ほぼReact、Vue、Angularの いずれかで安定している
 ● とはいえ、ライブラリ、フレームワーク自体のアップデートはそれなりに早い 
 ○ ソースの記述が古くなる可能性が高い 
 ○ 安定している or するだろうものであれば取り入れてしまったほうが良い 
 ● 周辺ツールも同様の傾向
 ○ Vue3から推奨ツールがvue cli→viteに 
 5
  6. 6. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 6 ● 新規プロジェクト(Nuxt.js)
 ● 社内の稼働時間管理ツール(Vue2→Vue3)
 ○ Vue2(Vue class component)からVue3にアップデート
 ● 社内のプロジェクト管理ツール(Vue3)
 ○ 作成段階からcomposition apiを利用
  7. 7. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 7
  8. 8. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 8 https://github.com/toranoana/wbs-front, https://github.com/toranoana/wbs-back
  9. 9. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 9
  10. 10. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 今回利用する環境
 10 ● macOS Big Sur
 ● TypeScript v4.1.3
 ● Node.js 14.17.0
 ● Vue 3.0.5
 ● Vite 2.3.3

  11. 11. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. このセッションについて
 11 ● 発表者が良いと思ったVue3の機能を紹介していきます
 ● メインの対象者
 ○ フロントエンドあまり触ったこと無い方
 ○ Vue2はやってたけどVue3についてはあまり知らない方
 ● 目標
 ○ 実際にVue3でアプリを作るときに大抵のことでは困らなくなる
 ● ソースコードはこちら 
 ○ https://github.com/toranoana/vue3-handson

  12. 12. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 12 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  13. 13. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. コンポーネントの基本
 13 ● Vue.jsはWebコンポーネントとVirtual DOMを軸にしたフレームワークです
 ○ Reactや、Angular(2以降)と似たフレームワークです
 ● *.vueという拡張子のファイルが画面の1パーツ(コンポーネント)となります。以下例です
 ○ Button.vue:ボタンのコンポーネント
 ○ Header.vue:ヘッダーのコンポーネント
 ○ App.vue:Button.vueとHeader.vueを組み合わせて画面を作るコンポーネント
  14. 14. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. コンポーネントの基本
 
 14 <template> <div id="app"> <div id="nav"> <!-- router/index.tsにかかれているルーティング情報から自動で aタグを作る --> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <!-- ルーティングされたコンポーネントがここに描画される--> <router-view /> </div> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "App", }); </script>
  15. 15. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. コンポーネントの基本
 
 15 App.vue
 router-link x 2
 router-view
 HelloWorld.vue

  16. 16. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 16
  17. 17. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 17 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  18. 18. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● setupメソッド
 ○ 各コンポーネントのエントリポイントとなるメソッド 
 ○ 呼ばれた段階ではまだレンダリングされていない状態 
 ● reactive関数
 ○ リアクティブなオブジェクトを作成できる 
 ○ リアクティブな状態が変化するとビューが自動的に更新される 
 ○ state.messageを更新すると、template側でstate.messageを使ってる部分も自動で変わる(後述) 
 18
  19. 19. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 
 <template> <div id="app"> <div id="nav"> <!-- 追加 --> <p>{{ state.message }}</p> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view /> </div> </template> 19 <script lang="ts"> import { defineComponent, reactive } from "vue"; interface State { message: string; } export default defineComponent({ name: "App", setup() { const state = reactive<State>({ message: "Hello Sample" }); return { state }; } }); </script>
  20. 20. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 20
  21. 21. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 
 21 <script lang="ts"> import Vue from "vue"; interface State { message: string; } export default Vue.extend({ name: "App", data(): State { return { state: { message: "Hello Sample" } }; } }); </script> Vue2の場合

  22. 22. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● Vue2まではdataメソッドから返されるものが自動でreactiveになっていた
 ○ →reactive関数として明示的に定義するようになったのでわかりやすく
 ● setup関数内ですべての処理を完結できるようになった
 ○ Vue2までは暗黙のうちにthisにプロパティが生えていた
 ○ 単なる関数の実行になるので理解しやすくなった
 22
  23. 23. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● 関数の作り方
 ○ setup関数内で関数を作り、戻り値として返す
 ○ template内で@clickなどで関数をイベントを紐付けする
 ● 表示の更新について
 ○ reactiveで生成した変数を、関数内で更新すると自動でtemplate内の表示も変わる
 ○ element.innerHTMLなどを利用した直接的なDOM書き換えは不要 23
  24. 24. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 <template> <div id="app"> <div id="nav"> <p>{{state.message}}</p> <!-- 追加 --> <p> <button type="button" @click="onClick">メッセージを変更 </button> </p> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view /> </div> </template 24
  25. 25. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 export default defineComponent({ name: "App", setup() { const state = reactive<State>({ message: "Hello Sample" }); const onClick = () => { state.message = "clicked"; }; return { state, onClick }; } }); 25
  26. 26. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 
 26 <script lang="ts"> import Vue from "vue"; interface State { message: string; } export default Vue.extend({ name: "App", data(): State { return { state: { message: "Hello Sample" } }; }, methods: { onClick() { this.state.message = "clicked"; } } }); </script> Vue2の場合

  27. 27. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● 関数もsetup内でただの変数として定義できる
 ○ スコープがsetup関数内になるのでthisなどの暗黙のお約束ごとは出てこない
 ○ 同様にmethodsプロパティも不要
 ○ 直感的
 ● 関数と関数で扱う値をセットで他のファイルに書くこともできる(後述)
 ○ コンポーネントとロジックを分離することでソースファイルを整理できる 27
  28. 28. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 import { AppState, useAppState } from './utils'; type State = AppState export default defineComponent({ name: "App", components: { Sample, Async }, setup() { const [state, onClick] = useAppState(); return { state, onClick }; } }); 28 reactiveな値と、値を変更する処理を別ファイルに書くこともでき る例(utils.ts)
 
 
 
 import { reactive } from "vue"; export interface AppState { message: string; } export const useAppState = (): [AppState, () => void] => { const state = reactive<AppState>({ message: "Hello Sample", }); const onClick = () => { state.message = "clicked"; }; return [state, onClick]; };
  29. 29. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● computed
 ○ Vue2までのcomputed propertyと同様 
 ○ 監視対象から計算される値を作る関数をセットすることで、値が変わったときに自動で再実行してく れる
 ○ 値が変わらない間はキャッシュされるので何回呼び出しても大丈夫 
 ● watchEffect
 ○ 関数内で使ってる変数を全て自動的に監視し、変更があった場合に関数を再度実行する 
 ● watch
 ○ 第1引数に与えた変数を監視し、第2引数の関数を呼び出す 
 ○ 明示的にチェックする変数を決めたい場合はこちら 
 ○ 他微妙に発火タイミング等の違いがある(特に初回) 
 29
  30. 30. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 <script lang="ts"> import { computed, watch, watchEffect, defineComponent, PropType, reactive, SetupContext, } from "vue"; interface State { localMessage: string; } export default defineComponent({ props: { parentMessage: { type: String, required: true, }, }, 30 値の監視をしたい場合 
 
 
 setup(props, { emit }: SetupContext) { const state = reactive<State>({ localMessage: "child component" }); const localFullMessage = computed( () => `localMessage: ${state.localMessage}` ); const parentFullMessage = computed( () => `parentMessage: ${props.parentMessage}` ); watchEffect(() => { alert(`localMessageかparentMessageが変更されました。 ${localFullMessage.value} ${parentFullMessage.value}` );}); watch(() => props.parentMessage, () => alert("parentMessageが変更されました。 ") ); return { state, emitClick, localFullMessage, parentFullMessage }; }, }); </script>
  31. 31. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Composition APIについて
 ● こちらも単なる関数(comuptedなど)の結果を変数として受けてそれを使うだけ
 ● watch系もコールバックをセットしているだけと考えれば理解しやすい
 ● computedで作った値をsetup関数内で扱うには.valueが必要なことは注意
 ○ template内ではそのまま変数として使えるので混乱ポイント
 31
  32. 32. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 32 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  33. 33. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Suspenseについて
 ● Suspense
 ○ レンダリング前の非同期処理を待ち受け、 待機中デフォルトテンプレートを表示する機能 
 ■ 主に非同期コンポーネントで利用(defineAsyncComponent) 
 ○ ただし、まだ実験中の機能 
 ■ 安定したものを使いたい場合はasync/awaitではなくthenを使うなど工夫が必要 
 ● async setupについて 
 ○ setup関数の事前処理などでAPIアクセスしたい場合かつawait使う場合に必要 
 ○ レンダリング前に発火されるので、setup関数自体の終了を待ち受けないといけない 
 ■ Suspenseの利用が必要 
 33
  34. 34. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Suspenseについて
 <script lang="ts"> import { defineComponent, reactive } from "vue"; import axios from "axios"; export default defineComponent({ async setup() { const state = reactive<State>({ apiData: null }); const res = await axios.get<CurrentPrice>( "https://api.coindesk.com/v1/bpi/currentprice.json" ); state.apiData = res.data; return { state }; }, }); </script> 34 setup関数をasyncにしてawaitを使う場合は工夫が必要(Suspense) 
 
 
 
 <template> <div id="app"> <!-- 略 --> <!-- Suspenseで囲むことで非同期コンポーネントの代替を表示--> <Suspense> <template #default> <async /> </template> <template #fallback> <div>loading...</div> </template> </Suspense> <!-- 略 --> </div> </template> (Async.vue) (App.vue)
  35. 35. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Suspenseについて
 ● フォールバックコンテンツを簡単に表示できるのはとても良い
 ○ シンタックスにも難しいところがない
 ● まだ安定してないのが最大の問題
 ○ thenを使う
 ○ onMountedに寄せる
 35
  36. 36. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 36 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  37. 37. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Fragmentsについて
 ● Fragmentsについて
 ○ Vue2ではコンポーネントのトップレベル要素は1つでなければいけなかった
 ○ Vue3からmulti-root nodeコンポーネントが作れるようになった
 ■ トップレベルに複数の要素があってもよい
 ○ 今まで暗黙のうちにトップレベルコンポーネントにバインドされてた要素は注意が必要
 ■ classを親側から差し込むと自動で一番上位の要素に付いていたりなど
 37
  38. 38. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Fragmentsについて 
 
 
 <template> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld v-bind="$attrs" msg="Hello Vue 3 + TypeScript + Vite" /> </template> <script lang="ts"> // 略 </script> 38 (Home.vue) <template> <div> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" /> </div> </template> <script lang="ts"> // 略 </script> (Vue2までのHome.vue)
  39. 39. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Fragmentsについて
 ● 不要な要素を入れる必要がなくなった 
 ● デザイナーがcss書いている場合は考慮してもらわないといけなかったが不要に 
 ● 自動で引き継がれていたプロパティは明示的にどのコンポーネントに付けるか指定が必要 
 ○ v-bind="$attrs"を付与する必要がある
 39
  40. 40. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 40 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  41. 41. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 ● Teleportについて
 ○ エレメントを指定した任意のエレメントの配下に移動できる
 ○ teleport要素が解釈されるときにteleport先のは存在していなければいけない
 ■ =Vueのコンポーネントを遷移先に指定することができない
 ■ mount済みかどうかでv-ifすることで一応回避できる
 41
  42. 42. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 
 42 (TeleportSample.vue)
 <template> <teleport to="#app"> <div>id=appにテレポートされてきた要素 </div> </teleport> <script lang="ts"> import { computed, defineComponent, onMounted, reactive } from 'vue' export default defineComponent({ setup() { }, }) </script>
  43. 43. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 
 43 <template> <a v-if="state.isLink" href="https://yumenosora.co.jp/tora-lab" id="link-container" target="_blank" > <p>リンクになってる画像 </p> </a> <span v-else id="not-link-container"> <p>リンクになってない画像 </p> </span> <teleport v-if="state.isMount" :to="targetContainerId"> <img src="https://yumenosora.co.jp/wp-content/themes/theme/assets/images/tora-lab/top_recruit.jpg" alt="とらラボエンジニア募集 " /> </teleport> <button @click="state.isLink = !state.isLink">リンク入れ替え</button> </template> 状況によって画像をリンクにするかどうか切り替えた い場合
  44. 44. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 
 44 <script lang="ts"> import { computed, defineComponent, onMounted, reactive } from "vue"; interface State { isLink: boolean; isMount: boolean; } export default defineComponent({ setup() { const state = reactive<State>({ isLink: true, isMount: false }); const targetContainerId = computed<string>(() => state.isLink ? "#link-container" : "#not-link-container" ); onMounted(() => (state.isMount = true)); return { state, targetContainerId }; }, }); </script>
  45. 45. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 
 45
  46. 46. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. Teleportについて
 ● エレメントの位置関係によるスタイルの調整とかがしやすいように
 ○ modalおよび伴うz-indexの都合など
 ○ 親エレメントのpositionに左右されにくくなる
 ● フラッシュメッセージとかにも使えるかも?
 ● Vueコンポーネント内のエレメントにTeleportするのはイマイチかも
 46
  47. 47. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 47 1. コンポーネントの基本 
 2. Composition APIについて 
 3. Suspenseについて
 4. Fragmentsについて 
 5. Teleportについて
 6. jsxについて

  48. 48. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. JSXについて
 
 
 48 import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import vueJsx from "@vitejs/plugin-vue-jsx"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue(), vueJsx()] }); Viteのプラグインを導入することでjsx/tsxを使うことができます 
 $ npm i @vitejs/plugin-vue-jsx -D vite.config.tsでプラグインを読み込み 

  49. 49. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. JSXについて
 
 
 49 <script lang="tsx"> import { defineComponent, reactive } from "vue"; interface State { message: string; clickCount: number; } Tsx.vueを作成
 export default defineComponent({ setup() { const state = reactive<State>({message: "test", clickCount: 0}); const onClick = () => { state.clickCount += 1; state.message = `${state.clickCount}回clickされました`; }; return () => ( <div class="home"> {state.message} <button onClick={onClick}>カウントボタン</button> </div> ); }, }); </script>
  50. 50. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. JSXについて
 ● JSXの良いところ
 ○ テンプレート内でも型推論がされやすくなる 
 ■ setup内の戻り値としてjsx返すだけなのである意味当然 
 ○ Vueの機能はそのまま使える 
 ■ scoped css
 ■ composition apiなど 
 ○ Reactやってきた人がすぐ入れそう 
 ○ 普通のVueコンポーネントと混ぜて使える 
 ● 微妙なところ
 ○ Vueである意味が薄くなる感がある 
 50
  51. 51. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. まとめ
 51 ● Vue3と各機能について説明しました 
 ○ 今までのVueをベースにより使いやすくなる機能が入っていると思います 
 ○ 個人的なイチオシはTeleport 
 ■ 外側のエレメントだけ変えたいときとかに使えるようになってくれると嬉しい 
 ○ JSXもComposition APIと合わせて既存のVueの弱点であったTypeScriptとの連携がいまいちな点 を解消できるので注目 
 ○ ライブラリの対応がまだいまいち 
 ■ Vuetify→2021Q3リリース目標 
 ■ Nuxt→対応中
 ○ ますますVue使いやすくなってるのでぜひ使ってみてください 


×