Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
はじめようVue3!

ハンズオンでとらのあなラボのフロントエンドを学ぶ



虎の穴ラボ 藤原 佳顕

1
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
アジェンダ

● 自己紹介

● なぜVue(3)か

● とらのあなラボでのVue(3)活用

● 今回利用する環境について

●...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
自己紹介

● 名前:藤原 佳顕

● 所属:虎の穴ラボ

● やっていること:(Fantia、)新規サービス、社内ツール、ソースレ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
なぜVue3か

● 一時期のフレームワークが群雄割拠していた時代に比べて、ほぼReact、Vue、Angularの
いずれかで安定...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
虎の穴ラボでのVue(3)活用

5
● 新規プロジェクト(Nuxt.js)

● 社内の稼働時間管理ツール(Vue2→Vue3)
...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
虎の穴ラボでのVue(3)活用

6
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
虎の穴ラボでのVue(3)活用

7
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
虎の穴ラボでのVue(3)活用

8
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
今回利用する環境

9
● macOS Big Sur

● TypeScript v4.1.3

● Node.js 14.17....
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
TypeScript:型付け

10
// 型はコロン(:)のあとに後置する形
// この関数はidという名前のnumber型の引数...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
TypeScript:型付け

11
// interfaceを使ってobjectなどに具体的な型を付けられる
interface ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
TypeScript:型付け

12
const meatMap = (store: Fuga) => {
console.log(...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
TypeScript:型付け

13
// 特集な型その1:インデックスシグネチャ 以下は数値のキーに対して文字列のvalueが紐づ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
TypeScript:型付け

14
// 特集な型その2:ユニオン型
interface Square {
kind: "squa...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ハンズオンについて

15
● メインの対象者

○ フロントエンドあまり触ったこと無い方

○ Vue2はやってたけどVue3のア...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ブランチまたはディレクトリ名:資料の見方とサンプルの動かし方

16
● サンプルリポジトリを動かすには、以下の手順が必要です

○...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
注意点と進め方

17
● 各ディレクトリで初回で動かす場合はディレクトリごとにnpm installが必要です


● 00.in...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

18
1. コンポーネントの基本(basic_of_component) 

2. stateについて

3. イベントに...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
basic_of_component:コンポーネントの基本

19
● Vue.jsはWebコンポーネントとVirtual DOMを...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue:ディレクトリ構成

20
❯ tree -L 2
.
├── README.md
├── index.html
├── pa...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
basic_of_component:コンポーネントの基本



21
<template>
<div id="app">
<div...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
basic_of_component:コンポーネントの基本



22
App.vue

router-link x 2

rout...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
23
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

24
1. コンポーネントの基本 

2. stateについて(state) 

3. イベントについて

4. コンポー...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
state:stateについて

● setupメソッド

○ 各コンポーネントのエントリポイントとなるメソッド 

○ 呼ばれた段...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
state:stateについて

<template>
<div id="app">
<div id="nav">
<!-- 追加 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
state:stateについて

一番上に”Hello Sample”が追
加される

27
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

28
1. コンポーネントの基本 

2. stateについて

3. イベントについて(event) 

4. コンポー...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
event:イベントについて

<template>
<div id="app">
<div id="nav">
<p>{{stat...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
event:イベントについて
 export default defineComponent({
name: "App",
setu...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
event:イベントについて

● 関数の作り方

○ setup関数内で関数を作り、戻り値として返す 

○ template内で...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
event:イベントについて

import { AppState, useAppState } from './utils';
t...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

33
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携(...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_props:コンポーネント間の連携






34
components/Sample.vueを作成

<sc...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_props:コンポーネント間の連携

<template>
<div id="app">
<div id="na...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_props:コンポーネント間の連携

● props

○ 親コンポーネントから渡ってくるデータ。変更不可 

...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue:コンポーネント間の連携

37
子コンポーネント(Sample.vue)内で親(App.vue)から渡された
propsが表...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

38
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_events:コンポーネント間の連携その2(propsの変更)



39
Sample.vueを変更

<te...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_events:コンポーネント間の連携その2(propsの変更)



40
Sample.vueを変更

pro...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_events:コンポーネント間の連携その2(propsの変更)



41
App.vueを変更

propsと...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_events:コンポーネント間の連携その2(propsの変更)



42
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
component_events:コンポーネント間の連携その2(propsの変更)



● propsとして関数受け渡し 

○ ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

44
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
lifecycle:ライフサイクルについて
● ReactやAngularなどと同様にライフサイクルがあります 

○ https:...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
lifecycle:ライフサイクルについて

46
views/Home.vueを変更

<script lang="ts">
//...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
47
Aboutページに行くとリサイズイベントが止まる 

Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

48
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajax)
● 生のXMLHttpRequestやfetch APIも使えますが、今回はライブラリを利用します...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajax)


50
● 今回はBitCoinの金額を取得するAPIを利用します(coindesk api)
...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajax)


51
components/Async.vueを作成

<template>
<pre v-i...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajax)


52
App.vueに追記

<template>
<div id="app">
<div i...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue:非同期通信(Ajax)


53
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajaxおまけ)


54
setup関数をasyncにしたい場合(Async.vue)

export de...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajaxおまけ)


55
App.vueでAsyncコンポーネントをSuspenseで囲む

<templa...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
ajax:非同期通信(Ajax)
● async setupとする場合はSuspenseが必要 

○ https://v3.ja....
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

57
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
computed_and_watch:computedとwatch


58
Sample.vueに追記

<div>
<!-- 以...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
computed_and_watch:computedとwatch


59
// computedとwatchとwatchEffe...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
computed_and_watch:computedとwatch

● watch、watchEffectを使うことでデータの監視...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
vue

61
1. コンポーネントの基本 

2. stateについて

3. イベントについて

4. コンポーネント間の連携 ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
routing:ルーティング 





62
<template>
<div>Topページ</div>
<Suspense>
<t...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
routing:ルーティング 





63
// 略
const routes: RouteRecordRaw[] = [
{ ...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
64
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
routing:ルーティング 

65
● 各パスに1コンポーネントが紐づく形になります 

○ 指定したコンポーネントがApp.v...
Copyright  (C) 2021 Toranoana Inc. All Rights Reserved.
まとめ

66
● Vue3と各機能について説明しました 

○ 単一コンポーネント内で完結するstateと更新処理について説明しま...
Upcoming SlideShare
Loading in …5
×
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0

Share

Download to read offline

はじめようVue3!ハンズオンでとらのあなラボのフロントエンドを学ぶ_20210611_TechDay#1

Download to read offline

2021/06/11 とらのあなラボTechDay#1 における登壇資料です
https://www.youtube.com/watch?v=PrU3roPxjz0

ソースコードはこちら
https://github.com/toranoana/vue3-handson

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

はじめようVue3!ハンズオンでとらのあなラボのフロントエンドを学ぶ_20210611_TechDay#1

  1. 1. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. はじめようVue3!
 ハンズオンでとらのあなラボのフロントエンドを学ぶ
 
 虎の穴ラボ 藤原 佳顕
 1
  2. 2. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. アジェンダ
 ● 自己紹介
 ● なぜVue(3)か
 ● とらのあなラボでのVue(3)活用
 ● 今回利用する環境について
 ● TypeScriptについて(今回は割愛)
 ● Vue3ハンズオン
 ● まとめ
 2
  3. 3. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 自己紹介
 ● 名前:藤原 佳顕
 ● 所属:虎の穴ラボ
 ● やっていること:(Fantia、)新規サービス、社内ツール、ソースレビュー
 ● 好きなもの:RustとかClojureとかDenoとか
 ● 好きなもの2:STG、音ゲー、格ゲー
 3
  4. 4. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. なぜVue3か
 ● 一時期のフレームワークが群雄割拠していた時代に比べて、ほぼReact、Vue、Angularの いずれかで安定している
 ● とはいえ、ライブラリ、フレームワーク自体のアップデートはそれなりに早い 
 ○ ソースの記述が古くなる可能性が高い 
 ○ 安定している or するだろうものであれば取り入れてしまったほうが良い 
 ● 周辺ツールも同様の傾向
 ○ Vue3から推奨ツールがvue cli→viteに 
 4
  5. 5. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 5 ● 新規プロジェクト(Nuxt.js)
 ● 社内の稼働時間管理ツール(Vue2→Vue3)
 ○ Vue2(Vue class component)からVue3にアップデート
 ● 社内のプロジェクト管理ツール(Vue3)
 ○ 作成段階からcomposition apiを利用
  6. 6. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 虎の穴ラボでのVue(3)活用
 6
  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
  9. 9. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 今回利用する環境
 9 ● macOS Big Sur
 ● TypeScript v4.1.3
 ● Node.js 14.17.0
 ○ これはインストールが必要です
 ○ docker用ファイルも用意してるのでそちらの利用でも構いません
 ● Vue 3.0.5
 ● Vite 2.3.3

  10. 10. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. TypeScript:型付け
 10 // 型はコロン(:)のあとに後置する形 // この関数はidという名前のnumber型の引数とnameという名前のstring型引数を取って、stringを返す関数 // ?がつく場合はオプションの引数となり渡さなくて良くなるが、関数内でチェックが必要 const hoge = (id: number, name: string, desc?: object): string => { let keys: string[] = []; if (desc) { keys = Object.keys(desc); } return `id: ${id}, name: ${name}, desc_keys: ${keys}`; }; // 型が推論できる場合は明示は不要 const a = 100; const b = "toranoana"; // 型がわからないときは any型になる(基本非推奨) const c: any = { a: 123, b: { c: 200 } }; console.log(hoge(a, b)); // any型だとどこにでも入れられてしまう console.log(hoge(a, b, c));
  11. 11. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. TypeScript:型付け
 11 // interfaceを使ってobjectなどに具体的な型を付けられる interface Fuga { ham: number; spam: number; storeName: string; } // interfaceを使った変数宣言 ?付きのオプションメンバー以外はすべてのメンバーが存在しないといけない const meatStore: Fuga = { ham: 100, spam: 200, storeName: "駅前肉屋" };
  12. 12. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. TypeScript:型付け
 12 const meatMap = (store: Fuga) => { console.log(`${store.storeName}にはhamが${store.ham}個、spamが${store.spam}個ありま す。`); } meatMap(meatStore); // ダックタイピングにより構造が一致してさえいれば呼び出せる meatMap({ham: 1, spam: 2, storeName: "2丁目肉屋" }); // Type Aliasという機能もあるが、基本的には interfaceをベースに使ったほうが良い // 長い名前に別名を付けたいときなどに利用 type FugaFuga = Fuga;
  13. 13. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. TypeScript:型付け
 13 // 特集な型その1:インデックスシグネチャ 以下は数値のキーに対して文字列のvalueが紐づくオブジェクトです const ranking: { [key: number]: string } = { 1: "aさん" }; ranking[2] = "Bさん"; // ranking["3"] = "Bさん"; // keyにnumber以外を渡すとエラー
  14. 14. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. TypeScript:型付け
 14 // 特集な型その2:ユニオン型 interface Square { kind: "square"; size: number; } interface Rectangle { kind: "rectangle"; width: number; height: number; } type Shape = Square | Rectangle; // パイプ(|)で区切ることでAかBという型を表現できる function menseki(s: Shape): number { if (s.kind === "square") { return s.size * s.size; } return s.width * s.height; }
  15. 15. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ハンズオンについて
 15 ● メインの対象者
 ○ フロントエンドあまり触ったこと無い方
 ○ Vue2はやってたけどVue3のアップデートにあまり知らない方
 ● 目標
 ○ 実際にVue3でアプリを作るときに大抵のことでは困らなくて良くなる
 ● ソースコードはこちら 
 ○ https://github.com/toranoana/vue3-handson

  16. 16. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ブランチまたはディレクトリ名:資料の見方とサンプルの動かし方
 16 ● サンプルリポジトリを動かすには、以下の手順が必要です
 ○ package.jsonがあるディレクトリでnpm install 
 ○ package.jsonがあるディレクトリでnpm run dev
 ○ http://localhost:3000にアクセス
 ○ dockerの環境も用意してますので、詳細はREADMEをお読みください
 ● 以降ではタイトルの左側に現在作業中のディレクトリ名を表示します
 ○ リポジトリのディレクトリを参照してください
 ○ 実際に手を動かさない場合でも対象のディレクトリを参照していただくことで何をしているか わかるかと思います
  17. 17. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 注意点と進め方
 17 ● 各ディレクトリで初回で動かす場合はディレクトリごとにnpm installが必要です 
 ● 00.init_templateが初期状態のディレクトリです 
 ○ こちらを拡張することでハンズオンを進めていきます 
 ● ソースを手打ちしていただいても良いですが、各ディレクトリのサンプルをコピペしていただいても問題ないです 
 ● ソース及び発表資料は公開いたしますので、途中でついていけなくなった方などは後日参照いただければと思い ます
 ● 割愛させて頂く部分が発生するかもしれませんが、その際も公開された資料をご確認ください 
 ● 今回は申し訳ありませんが、環境が動かない等のフォローはできない可能性があります。その際はソースの方を 追っていただければと思います 

  18. 18. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 18 1. コンポーネントの基本(basic_of_component) 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて←ここまでは実施予定 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  19. 19. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. basic_of_component:コンポーネントの基本
 19 ● Vue.jsはWebコンポーネントとVirtual DOMを軸にしたフレームワークです
 ○ Reactや、Angular(2以降)と似たフレームワークです
 ● *.vueという拡張子のファイルが画面の1パーツ(コンポーネント)となります。以下例です
 ○ Button.vue:ボタンのコンポーネント
 ○ Header.vue:ヘッダーのコンポーネント
 ○ App.vue:Button.vueとHeader.vueを組み合わせて画面を作るコンポーネント
  20. 20. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue:ディレクトリ構成
 20 ❯ tree -L 2 . ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public ├── src │ ├── App.vue │ ├── assets │ ├── components │ ├── main.ts │ ├── router │ ├── shims-vue.d.ts │ ├── store │ └── views ├── tsconfig.json └── vite.config.ts コンポーネントのエントリポイント プログラムのエントリポイント ルーティングに関するファイル置き場 *.vueファイルをTypeScriptに認識させるための型定義 Vuexに関するファイル置き場 URLと紐づくコンポーネントの置き場 小分けされたコンポーネント置き場 画像などの静的なファイル置き場
  21. 21. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. basic_of_component:コンポーネントの基本
 
 21 <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>
  22. 22. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. basic_of_component:コンポーネントの基本
 
 22 App.vue
 router-link x 2
 router-view
 HelloWorld.vue

  23. 23. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 23
  24. 24. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 24 1. コンポーネントの基本 
 2. stateについて(state) 
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  25. 25. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. state:stateについて
 ● setupメソッド
 ○ 各コンポーネントのエントリポイントとなるメソッド 
 ○ 呼ばれた段階ではまだレンダリングされていない状態 
 ● reactive関数
 ○ リアクティブなオブジェクトを作成できる 
 ○ リアクティブな状態が変化するとビューが自動的に更新される 
 ○ state.messageを更新すると、template側でstate.messageを使ってる部分も自動で変わる(後述) 
 25
  26. 26. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. state:stateについて
 <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> 26 <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>
  27. 27. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. state:stateについて
 一番上に”Hello Sample”が追 加される
 27
  28. 28. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 28 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて(event) 
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  29. 29. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. event:イベントについて
 <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 29
  30. 30. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. event:イベントについて
 export default defineComponent({ name: "App", setup() { const state = reactive<State>({ message: "Hello Sample" }); // 追加 const onClick = () => { state.message = "clicked"; }; return { state, // 追加 onClick }; } }); 30
  31. 31. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. event:イベントについて
 ● 関数の作り方
 ○ setup関数内で関数を作り、戻り値として返す 
 ○ template内で@clickなどで関数をイベントを紐付けする 
 ○ reactiveな値と共に別ファイルに書くこともできる(次ページ) 
 ● 表示の更新について 
 ○ reactiveで生成した変数を、関数内で更新すると自動でtemplate内の表示も変わる 
 ○ element.innerHTMLなどを利用した直接的なDOM書き換えは不要 31
  32. 32. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. event:イベントについて
 import { AppState, useAppState } from './utils'; type State = AppState export default defineComponent({ name: "App", components: { Sample, Async }, setup() { const [state, onClick] = useAppState(); return { state, onClick }; } }); 32 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]; };
  33. 33. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 33 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携(component_props) 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  34. 34. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_props:コンポーネント間の連携 
 
 
 34 components/Sample.vueを作成
 <script lang="ts"> import { defineComponent } from "vue" interface State { localMessage: string; } export default defineComponent({ props: { parentMessage: { type: String, required: true, }, }, setup() { const state = reactive<State>({ localMessage: "child component" }); return { state }; }, }); </ script> <template> <div> <p>localMessage: {{ state.localMessage }}</p> <p>parentMessage: {{ parentMessage }}</p> </div> </template>
  35. 35. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_props:コンポーネント間の連携
 <template> <div id="app"> <div id="nav"> <!-- 追加 --> <sample :parent-message="state.message" /> <!-- <p>{{ state.message }}</p> --> <!-- 以下略 --> </template> 35 <script lang="ts"> import { defineComponent, reactive } from "vue"; import Sample from './components/Sample.vue'; interface State { message: string; } export default defineComponent({ name: "App", // 追加 components: { Sample }, // 以下略 }); </script> App.vueを変更

  36. 36. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_props:コンポーネント間の連携
 ● props
 ○ 親コンポーネントから渡ってくるデータ。変更不可 
 ■ 変更したい場合は変更用の処理を一緒に渡す(後述) 
 ○ プリミティブな値だけでなく、objectや関数も渡せる 
 ● 子コンポーネントの埋め込み方 
 ○ defineComponent内にcomponentsプロパティを追加 
 ○ template内でカスタムタグのように子コンポーネントを埋め込み 
 ● propsの渡し方について 
 ○ :`props名` で受け渡す 
 ■ v-bind:`prps名` のシンタックスシュガー 36
  37. 37. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue:コンポーネント間の連携
 37 子コンポーネント(Sample.vue)内で親(App.vue)から渡された propsが表示される
 
 
 親での変更がpropsにも反映され、表示が変わる

  38. 38. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 38 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更、component_events) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  39. 39. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_events:コンポーネント間の連携その2(propsの変更)
 
 39 Sample.vueを変更
 <template> <div> <p>localMessage: {{ state.localMessage }}</p> <p>parentMessage: {{ parentMessage }}</p> </div> <!-- 以下追加 --> <p> <button type="button" @click="updateMessage">propで更新</button> </p> <p> <button type="button" @click="emitClick">emitで更新</button> </p> </template>
  40. 40. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_events:コンポーネント間の連携その2(propsの変更)
 
 40 Sample.vueを変更
 propsで変更用の関数を受け取る場合と、Eventで受け取る場合を追加
 <script lang="ts"> // 略 export default defineComponent({ props: { // 略 // 追加(propsで変更用の関数を受け取るケース ) updateMessage: { type: Function as PropType<() => void>, default: () => {}, }, }, emits: ["click"], setup(_, { emit }: SetupContext) { // 略 // 追加(Eventとして変更用の関数を受け取るケース ) const emitClick = () => { emit("click"); }; return { state, emitClick, // 追加 }; }, }); </script>
  41. 41. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_events:コンポーネント間の連携その2(propsの変更)
 
 41 App.vueを変更
 propsとEventを渡すようにする
 <template> <div id="app"> <div id="nav"> <!-- 追加(propsと@click) --> <sample :parent-message="state.message" @click="onChildEmit" :update-message="onChildClick" /> <!-- 以下略 --> </template> <script lang="ts"> // 略 export default defineComponent({ // 略 setup() { // 略 // 追加(2つ) const onChildClick = () => { state.message = "child clicked"; }; const onChildEmit = () => { state.message = "child emit clicked"; }; return { state, onClick, // 追加(2つ) onChildClick, onChildEmit, }; }, }); </script>
  42. 42. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_events:コンポーネント間の連携その2(propsの変更)
 
 42
  43. 43. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. component_events:コンポーネント間の連携その2(propsの変更)
 
 ● propsとして関数受け渡し 
 ○ typeにFunctionを指定することでpropsとして関数を受け取れるようにする 
 ○ 関数の具体的な型はPropTypeを使うことで明示できる 
 ● Eventとしての関数受け渡し 
 ○ defineComponentのプロパティとしてemitsを追加(Vue3から) 
 ■ 呼び出す可能性のあるEvent一覧を文字列で追加 
 ■ objectで指定することで引数等のバリデーションも可能(今回は割愛) 
 ○ setup関数の第二引数、SetupContextのメンバーとしてemit関数がある 
 ○ emit(`呼びたいEvent名`, `引数`)で関数呼び出しできる 
 ■ 文字列で関数を呼び出すため具体的な型がつけにくい 43
  44. 44. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 44 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて(lifecycle) 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング

  45. 45. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. lifecycle:ライフサイクルについて ● ReactやAngularなどと同様にライフサイクルがあります 
 ○ https://v3.vuejs.org/guide/composition-api-lifecycle-hooks.html 
 ○ Vue2であったcreatedはsetupに統合されました 
 ● よく使うもの
 ○ mounted
 ■ DOMに触れられるようになったタイミングで発火 
 ○ unmounted
 ■ コンポーネントが破棄されるとき 
 ■ windowに何かしらイベント付けてるときの破棄などに使う(メモリリーク防止) 
 45
  46. 46. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. lifecycle:ライフサイクルについて
 46 views/Home.vueを変更
 <script lang="ts"> // ライフサイクルのHookメソッドを追加 import { defineComponent, onMounted, onUnmounted } from "vue"; import HelloWorld from "../components/HelloWorld.vue"; export default defineComponent({ // 略 // setupメソッド追加 setup() { const resizeEvent = () => { console.log("resize window"); }; onMounted(() => { window.addEventListener("resize", resizeEvent); }); onUnmounted(() => { window.removeEventListener("resize", resizeEvent); }); }, }); </script>
  47. 47. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 47 Aboutページに行くとリサイズイベントが止まる 

  48. 48. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 48 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(ajax)
 8. computedとwatch
 9. ルーティング

  49. 49. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajax) ● 生のXMLHttpRequestやfetch APIも使えますが、今回はライブラリを利用します 
 ○ https://github.com/axios/axios 
 ○ npm install axios @types/axios 
 ○ サンプルのリポジトリにはインストール済みです 
 ○ コンポーネントマウント前にデータ取得開始→state変更といった流れにします 
 49
  50. 50. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajax) 
 50 ● 今回はBitCoinの金額を取得するAPIを利用します(coindesk api)
 ○ https://api.coindesk.com/v1/bpi/currentprice.json
 APIのレスポンスの型は次のものを想定
 interface Time { updated: string; updatedISO: string; updateduk: string; } interface Bpi { code: string; symbol: string; rate: string; description: string; rate_float: number; } interface CurrentPrice { time: Time; disclaimer: string; chartName: string; bpi: { USD: Bpi; GBP: Bpi; EUR: Bpi; }; }
  51. 51. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajax) 
 51 components/Async.vueを作成
 <template> <pre v-if="state.apiData"> <code> {{ state.apiData }} </code> </pre> </template> <script lang="ts"> import { defineComponent, reactive } from "vue"; import axios from "axios"; // APIのinterfaceは略(前ページ参照) interface State { apiData: CurrentPrice | null; } export default defineComponent({ setup() { const state = reactive<State>({ apiData: null }); axios .get<CurrentPrice>("https://api.coindesk.com/v1/bpi/currentprice.json") .then((res) => { state.apiData = res.data; }); return { state, }; }, }); </script> <style scoped> pre { height: 300px; overflow: scroll; border: solid 1px #8a8a8a; } </style>
  52. 52. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajax) 
 52 App.vueに追記
 <template> <div id="app"> <div id="nav"> <!-- 略 --> <async /> <!-- 略 → </div> <router-view /> </div> </template> <script lang="ts"> import { defineComponent, onMounted, onUnmounted, reactive } from "vue"; import Sample from "./components/Sample.vue"; // 追加 import Async from "./components/Async.vue"; interface State { message: string; } export default defineComponent({ name: "App", // Async追加 components: { Sample, Async }, // 略 }); </script>
  53. 53. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue:非同期通信(Ajax) 
 53
  54. 54. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajaxおまけ) 
 54 setup関数をasyncにしたい場合(Async.vue)
 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, }; }, });
  55. 55. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajaxおまけ) 
 55 App.vueでAsyncコンポーネントをSuspenseで囲む
 <template> <!-- 略 --> <!-- 追加:Supenseで囲むことで非同期コンポーネントのフォールバックコンテンツを表示 --> <Suspense> <template #default> <async /> </template> <template #fallback> <div>loading...</div> </template> </Suspense> <!-- 略 --> </template>
  56. 56. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. ajax:非同期通信(Ajax) ● async setupとする場合はSuspenseが必要 
 ○ https://v3.ja.vuejs.org/guide/migration/suspense.html 
 ● Suspense自体は非同期コンポーネントの描画を待つ間、代わりを表示する機能 
 ○ Suspenseなしasync setupなコンポーネントの部分は何も描画されなくなります 
 ● Vue2でのasync createdのつもりで使うと引っかかるかもしれないので注意 
 56
  57. 57. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 57 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch(computed_and_watch) 
 9. ルーティング

  58. 58. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. computed_and_watch:computedとwatch 
 58 Sample.vueに追記
 <div> <!-- 以下2つに変更 --> <p>{{ localFullMessage }}</p> <p>{{ parentFullMessage }}</p> </div> <p> <button type="button" @click="updateMessage">propで更新</button> </p> <p> <button type="button" @click="emitClick">emitで更新</button> </p> </template>
  59. 59. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. computed_and_watch:computedとwatch 
 59 // computedとwatchとwatchEffect追加 import { computed, watch, watchEffect, /* 略 */ } from "vue"; // 略 export default defineComponent({ // 略、propsをsetupの引数に追加 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が変更されました。 ") ); const emitClick = () => { emit("click"); }; return { // 追加(localFullMessage、parentFullMessage) state, emitClick, localFullMessage, parentFullMessage, }; }, }); </script>
  60. 60. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. computed_and_watch:computedとwatch
 ● watch、watchEffectを使うことでデータの監視が可能 
 ○ watchEffect:コールバックに指定した関数の中で使ってるリアクティブな変数が変更されたら関数 を再度実行する
 ○ watch:第一引数に指定した変数が変更されたら第2引数の関数を再度実行する 
 ● computedを使うことでデータに加工が可能 
 ○ 不変でreactiveなrefオブジェクトを返す関数 
 ○ computed内で使ってる変数が変更されると戻り値もリアクティブに変更される 
 60
  61. 61. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. vue
 61 1. コンポーネントの基本 
 2. stateについて
 3. イベントについて
 4. コンポーネント間の連携 
 5. コンポーネント間の連携その2(propsの変更) 
 6. ライフサイクルについて 
 7. 非同期通信(Ajax)
 8. computedとwatch
 9. ルーティング(routing) 

  62. 62. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. routing:ルーティング 
 
 
 62 <template> <div>Topページ</div> <Suspense> <template #default> <async /> </template> <template #fallback> <div>loading...</div> </template> </Suspense> </template> <script lang="ts"> import { defineComponent } from "vue"; import Async from "../components/Async.vue"; export default defineComponent({ components: { Async }, }); </script> URLとコンポーネントを紐付けるために、views/Top.vueを作成 
 中身では先程作成したAsync.vueを表示してみます 

  63. 63. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. routing:ルーティング 
 
 
 63 // 略 const routes: RouteRecordRaw[] = [ { path: '/', component: Home }, { path: '/about', component: About }, // 追加 { path: '/top', component: Top }, ]; export const router = createRouter({ history: createWebHistory(), routes, }); <template> <div id="app"> <div id="nav"> <!-- 略 --> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <!-- 追加 --> <router-link to="/top">Top</router-link> </div> <router-view /> </div> </template> 続いて、router/index.tsとApp.vueを変更 
 (router/index.ts)
 (App.vue)

  64. 64. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. 64
  65. 65. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. routing:ルーティング 
 65 ● 各パスに1コンポーネントが紐づく形になります 
 ○ 指定したコンポーネントがApp.vueの<router-view />に入ります 
 ● コンポーネントを非同期ロードすることも可能 
 ○ ダイナミックインポートしたコンポーネントをパスに紐付ける 
 ○ 画面ロード時のファイルサイズを小さくすることができる 
 { path: '/top', component: () => import(/* webpackChunkName: "top" */ '../views/Top.vue') },
  66. 66. Copyright  (C) 2021 Toranoana Inc. All Rights Reserved. まとめ
 66 ● Vue3と各機能について説明しました 
 ○ 単一コンポーネント内で完結するstateと更新処理について説明しました 
 ○ propsやeventを通したコンポーネント間の連携について説明しました 
 ○ Vue3は昨年リリースされたばかりの新しいフレームワークです 
 ○ Vue3での実際のアプリケーションの使い方について説明しました 
 ○ 説明してませんが、周辺ライブラリがVue3の記述に追いついてない場合があるので注意 
 ○ 公開するスライドには説明しなかった部分も含まれるのでぜひ見てみてください 


2021/06/11 とらのあなラボTechDay#1 における登壇資料です https://www.youtube.com/watch?v=PrU3roPxjz0 ソースコードはこちら https://github.com/toranoana/vue3-handson

Views

Total views

544

On Slideshare

0

From embeds

0

Number of embeds

482

Actions

Downloads

0

Shares

0

Comments

0

Likes

0

×