Slide 1

Slide 1 text

プロダクトに 1 から Vue.js を取り入れた話 マーケティング事業の開発現場でリアルに使われるJS事情

Slide 2

Slide 2 text

岡田 正平(おかだ しょうへい)@okashoi • 開発グループ ソリューションユニット所属 • 2015年にウィルゲートに新卒入社(3年目) • サーバサイドエンジニア • PHP / Laravel • Vue.js をチームに導入した立場のお話をします 2 自己紹介

Slide 3

Slide 3 text

宮西 由貴(みやにし ゆうき) • 開発グループ ソリューションユニット所属 • 2016年にウィルゲートに新卒入社(2年目) • フロントエンド勉強中 • Vue.js の導入を受けたメンバーの立場から お話をします 3 自己紹介

Slide 4

Slide 4 text

4 ウィルゲートの事業

Slide 5

Slide 5 text

• 前半パート「チームに導入した話」@岡田 • 後半パート「実際に使った話」@宮西 5 構成

Slide 6

Slide 6 text

前半パート: チームに導入した話

Slide 7

Slide 7 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 7 アジェンダ

Slide 8

Slide 8 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 8 アジェンダ

Slide 9

Slide 9 text

• 4人チーム(2017年4月1日時点) • 全員がサーバサイド • 社内システム開発がメイン • ロジックの堅牢性が重視される • 画面はほとんどが動きが無い • JS は jQuery ベース • 非同期処理をするのは稀 9 背景 | Vue.js 導入前のチーム状況

Slide 10

Slide 10 text

• 2017年4月から新規プロダクトの開発が始まる • web コンサルティングのノウハウをシステム化 • 「動きのある」画面が必要になってくる • 画面操作に応じて Ajax 通信でデータを取得 • 画面操作に応じてグラフを動的に描画 ➢ チームとして、リッチな画面をつくる力を付ける必要がある(課題) 10 背景 | きっかけ

Slide 11

Slide 11 text

その一方で • web アプリケーションフレームワークに Laravel を使ってきた • その Laravel が 5.3 より Vue.js を公式採用 → これを受けて個人的な興味から触ってみる → いい感触を得た • データの操作と表示の更新を分離 • 小さく始められる 11 背景 | きっかけ

Slide 12

Slide 12 text

その一方で • web アプリケーションフレームワークに Laravel を使ってきた • その Laravel が 5.3 より Vue.js を公式採用 → これを受けて個人的な興味から触ってみる → いい感触を得た • データの操作と表示の更新を分離 • 小さく始められる ➢ チームの課題を解決できるのでは? → Vue.js 導入へ 12 背景 | きっかけ

Slide 13

Slide 13 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 13 アジェンダ

Slide 14

Slide 14 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス 14 導入のためにやったこと

Slide 15

Slide 15 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス 15 導入のためにやったこと

Slide 16

Slide 16 text

16 チュートリアルを作成

Slide 17

Slide 17 text

• ハンズオン形式 • 30 分程度 • 【題材】行を動的に増減させられる表をつくる • 過去に辛かった実装例を持ち出して Vue.js の威力を感じてもらう • 基本的なプロパティ・ディレクティブの使い方や コンポーネントのつくり方を身につけられるもの • 資料は公開した • https://github.com/okashoi/vue-js-handson/ 17 チュートリアルを作成

Slide 18

Slide 18 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス 18 導入のためにやったこと

Slide 19

Slide 19 text

• ビルドシステム(gulp, webpack等)は使わない • 小さく始めるため • 一度に新しい概念を導入することによる混乱を避けるため • Vue.js を強制しない • メンバー間のスキルが不均一な状態 • Vue.js 導入によって開発にブレーキが掛かるのを懸念 • 「こういうところに使う」部分だけすりあわせておく • 基本ルールを設け、それを Confluence 上に明文化 ➢ あとは個別にフォローアップ(後述) 19 方針を整備

Slide 20

Slide 20 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス 20 導入のためにやったこと

Slide 21

Slide 21 text

• はじめは、メンバーには席の横に付きながら 一緒にロジックを構築していく • slack や プルリクへのコメント で Tips を共有 • 「なぜこうするとよいか」をあわせて説明 21 メンバーへのアドバイス

Slide 22

Slide 22 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス 22 導入のためにやったこと

Slide 23

Slide 23 text

• チュートリアルを作成 • 方針を整備 • メンバーへのアドバイス ➢ チームとして Vue.js を使っている状態に 23 導入のためにやったこと

Slide 24

Slide 24 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 24 アジェンダ

Slide 25

Slide 25 text

• 複雑な挙動の画面の実装を想定より早く、バグも少なく実装できた • jQuery オンリーだったら実装困難だったかもしれない • 詳細は後半の部で • 新しいメンバーの受け入れがスムーズに進んだ • チュートリアルを資料として残せた • Vue.js 自体の学習しやすさも助けになっている • 小さく始めたことでチームメンバーが自発的に学習していってくれた • 「Vue.js の良さ」が伝わった結果 25 良かったこと

Slide 26

Slide 26 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 26 アジェンダ

Slide 27

Slide 27 text

• フロント設計の必要性を理解した • 1,000行に及ぶ new Vue() とか。。。 • 「Vue.js を強制しなかった」ことが裏目に出た • 人・時期によって使われ方がまちまち • 「画面全体 Vue.js」vs.「一箇所の挙動だけ Vue.js」 • 規模に依らないことは Vue.js の利点だが、プロジェクト内では統一すべき • npm 等のパッケージ管理ツールを使わないと辛い目を見がち • モジュール(vue-〇〇 的なやつら)が使えなかったりする • ちょっとしたハックをして使うこともある 27 学んだこと

Slide 28

Slide 28 text

1. 背景 2. 導入のためにやったこと 3. 良かったこと 4. 学んだこと 5. 今後の展望 28 アジェンダ

Slide 29

Slide 29 text

• 「フロントの設計」を身につける • 状態の管理、ロジックの切り分け、コンポーネントへの分け方... • ビルドシステムの導入 • Laravel の Vue.js 公式採用の真価を発揮(Laravel Mix) • パッケージ管理, ES6記法, bundle化, .vue ファイル 等の恩恵 29 今後の展望

Slide 30

Slide 30 text

後半パート: 実際に使った話

Slide 31

Slide 31 text

1. 背景 2. 導入前と導入後のコード比較 1. 新規プロダクトで開発した機能 2. 導入前の状態 3. 導入後の状態 3. まとめ 1. 導入してよかった点 2. 今後できたらいいこと 31 アジェンダ

Slide 32

Slide 32 text

1. 背景 2. 導入前と導入後のコード比較 1. 新規プロダクトで開発した機能 2. 導入前の状態 3. 導入後の状態 3. まとめ 1. 導入してよかった点 2. 今後できたらいいこと 32 アジェンダ

Slide 33

Slide 33 text

• 社内ツールをメインに開発 • 新規プロダクトの開発が決定 • 今までに比べてリッチな画面が求められる • Vue.jsの導入が決定 • 開発開始(2017年06月~) • 1次フェーズの開発が完了(2017年10月) 33 Vue.js導入前後のできごと(時系列順)

Slide 34

Slide 34 text

• 社内ツールをメインに開発 • 新規プロダクトの開発が決定 • 今までに比べてリッチな画面が求められる • Vue.jsの導入が決定 • 開発開始(2017年06月~) • 1次フェーズの開発が完了(2017年10月) 34 Vue.js導入前後のできごと(時系列順)

Slide 35

Slide 35 text

• jQueryを駆使して画面を作成できる • 処理を再利用できていない • JS側に大量のHTMLタグをベタ書きしている • 状態の管理が複雑になっている • 要素にどんな状態が存在するのかわかりにくい • 要素の「状態」を見て処理を分けている 35 これまでの私のJSレベル

Slide 36

Slide 36 text

• jQueryを駆使して画面を作成できる • 処理を再利用できていない • JS側に大量のHTMLタグをベタ書きしている • 状態の管理が複雑になっている • 要素にどんな状態が存在するのかわかりにくい • 要素の「状態」を見て処理を分けている 36 これまでの私のJSレベル

Slide 37

Slide 37 text

「状態」の管理がピタゴラ装置 37 頑張るJSがそこに在る // クリック禁止状態だった場合は何もせずに終了 if ($(e.target).css(‘cursor’) == ‘not-allowed‘) { return false; } // メッセージを表示し、編集ボタンを無効化 if (!$('.js-btn-update-target-areas').prop('disabled')) { $('.js-message-target-areas-changed').prop('hidden', false); $('a.js-open-modal-update-modification-order').css('cursor', 'not-allowed'); } // 更新を可能にする $('.js-btn-update-target-areas').prop('disabled', false);

Slide 38

Slide 38 text

「状態」の管理がピタゴラ装置 38 頑張るJSがそこに在る // クリック禁止状態だった場合は何もせずに終了 if ($(e.target).css(‘cursor’) == ‘not-allowed‘) { return false; } // メッセージを表示し、編集ボタンを無効化 if (!$('.js-btn-update-target-areas').prop('disabled')) { $('.js-message-target-areas-changed').prop('hidden', false); $('a.js-open-modal-update-modification-order').css('cursor', 'not-allowed'); } // 更新を可能にする $('.js-btn-update-target-areas').prop('disabled', false);

Slide 39

Slide 39 text

• 社内ツールをメインに開発 • 新規プロダクトの開発が決定 • 今までに比べてリッチな画面が求められる • Vue.jsの導入が決定 • 開発開始(2017年06月~) • 1次フェーズの開発が完了(2017年10月) 39 Vue.js導入前後のできごと(時系列順) もしVue.js導入前に 実装したら… vs Vue.js導入後の 実装では…

Slide 40

Slide 40 text

1. 背景 2. 導入前と導入後のコード比較 1. 新規プロダクトで開発した機能 2. 導入前の状態 3. 導入後の状態 3. まとめ 1. 導入してよかった点 2. 今後できたらいいこと 40 アジェンダ

Slide 41

Slide 41 text

• 値の編集が可能な表 • 送信前に値のバリデーションを行う • 選択した条件でデータを絞り込む機能 • グラフ、表が複数存在する画面 • 期間を指定するとグラフ・表の内容が変化 41 開発した機能

Slide 42

Slide 42 text

• 値の編集が可能な表 • 送信前に値のバリデーションを行う • 選択した条件でデータを絞り込む機能 • グラフ、表が複数存在する画面 • 期間を指定するとグラフ・表の内容が変化 42 開発した機能

Slide 43

Slide 43 text

43 値の編集が可能な表

Slide 44

Slide 44 text

44 値の編集が可能な表 重複禁止 / 150文字以内 正の整数のみ許可

Slide 45

Slide 45 text

• ボタン押下時の処理にバリデーションを大量に記述 • 表の要素をすべて取得 • $.eachで1要素ずつ確認 45 Vue.js導入前 $.each(selectedKeywords, function (index, selectedElemet) { // 要素の入力チェック if (isInput != isEmpty(selectedElemet.hoge)) { // 略 } // 要素の重複チェック if (selectedElemet.hoge in keywordListWithDuplication) { // 略 } else { // 略 } // 以下略 });

Slide 46

Slide 46 text

• v-modelを使ってユーザの入力を双方向バインディング • 編集後の値を使った処理も簡単 • バリデーション • 値を使った計算結果の表示 46 Vue.js導入後

Slide 47

Slide 47 text

• v-modelを使ってユーザの入力を双方向バインディング • 編集後の値を使った処理も簡単 • バリデーション • 値を使った計算結果の表示 47 Vue.js導入後 methods: { // elementChangedメソッド: 要素に0以下の値が入力された場合 // 自動で0に修正する // 小数の場合は小数部分を切り捨てる elementChanged: function(element) { element.value = Math.floor(element.value); if (element.value < 0) { element.value = 0; } } }

Slide 48

Slide 48 text

• 値の編集が可能な表 • ボタンを押下した際に値のバリデーションを行う • 選択した条件でデータを絞り込む機能 • グラフ、表が複数存在する画面 • 期間を指定するとグラフ・表の内容が変化 48 開発した機能

Slide 49

Slide 49 text

49 選択した条件でデータを絞り込む機能

Slide 50

Slide 50 text

50 選択した条件でデータを絞り込む機能 絞り込み機能

Slide 51

Slide 51 text

• データをJS側で絞り込んだ後、表を再描画 • 表の再描画時に大量のHTMLをベタ書き 51 Vue.js導入前① tableCheckBoxId = 'goal' + goalInfo['id']; tableCheckBox = ''; tableId = '
' + goalInfo['id_at_hoge'] + '
';

Slide 52

Slide 52 text

• JS側でデータを変更したら画面側は動的に変化 52 Vue.js導入後①

Slide 53

Slide 53 text

• 絞り込み条件に対するバリデーションをいたるところに記載 • 絞り込むボタンを押下した際にチェックが走る 53 Vue.js導入前② // ----------------------------------- // 絞り込み機能 // ----------------------------------- // 要素1の絞り込み指定範囲内のものだけを表示 $('.js-button-check-condition1').on('click', function(e) { // バリデーションと絞り込み処理 }); // 要素2の絞り込み指定範囲内のものだけを表示 $('.js-button-check-condition2').on('click', function(e) { // バリデーションと絞り込み処理 });

Slide 54

Slide 54 text

• 役割を分けて処理を記述できる • watch:リアルタイムなバリデーション • methods: データの絞り込み処理 • computed: データを使った計算 • filter: 表示用に値を整形(例:1000円 → 1,000円) 54 Vue.js導入後② watch: { filterConditions: { handler: function (conditions) { // 非負値のみ許可 if (conditions.hoge.lower < 0) { conditions.hoge.lower = 0 } // 以下略 }, deep: true } }

Slide 55

Slide 55 text

• 値の編集が可能な表 • ボタンを押下した際に値のバリデーションを行う • 選択した条件でデータを絞り込む機能 • グラフ、表が複数存在する画面 • 期間を指定するとグラフ・表の内容が変化 55 開発した機能

Slide 56

Slide 56 text

56 グラフ、表が複数存在する画面

Slide 57

Slide 57 text

• グラフの数だけ、似たような処理を記述 • 初期のグラフ表示用の設定 • グラフのデータが変わった時の処理 • 変更があった時に直し漏れが発生する危険性 • コピペが大量発生 • コード量が多くて直す箇所が分かりにくい 57 Vue.js導入前

Slide 58

Slide 58 text

58 Vue.js導入前 // パターンに紐付く データおよび軸 の設定をそれぞれ行う // 追加でテーブルへの表示もこちらで行う switch (patternId) { // ほげのグラフ case patternIds['hoge'] : _createHogeDatasets(); config.options.scales = hogeScales; break; // ふがのグラフ case patternIds['fuga'] : _createFugaDatasets(); config.options.scales = fugaScales; break;

Slide 59

Slide 59 text

• グラフの作成にはChart.jsを使用 • vue-chartjsというVue.js用のプラグインを使用した • vue-chartjsにはグラフ用のコンポーネントがある 59 Vue.js導入後 http://vue-chartjs.org/

Slide 60

Slide 60 text

• グラフの種類によってコンポーネント化 • データが異なる同じ種類のグラフに対応 • グラフの更新は、データをコンポーネントに渡すだけ 60 Vue.js導入後 //------------------ // 円グラフ //------------------ Vue.component('pie-chart', { extends: VueChartJs.Pie, mixins: [VueChartJs.mixins.reactiveProp], props: ['options'], mounted: function () { this.renderChart(this.chartData, this.options); } });

Slide 61

Slide 61 text

61 Vue.js導入後

Slide 62

Slide 62 text

1. 背景 2. 導入前と導入後のコード比較 1. 新規プロダクトで開発した機能 2. 導入前の状態 3. 導入後の状態 3. まとめ 1. 導入してよかった点 2. 今後できたらいいこと 62 アジェンダ

Slide 63

Slide 63 text

• データの変更があった際の画面への反映が簡単 • 導入前:JS側でデータ変更→画面側に反映させる処理 が必要 • 導入後:JS側でデータ変更→自動で画面側に反映される • コードが読みやすくなった • データ処理と表示処理が分離されている • データ処理の内部でも処理が用途に分かれている (computed, method, filtersなど) • コンポーネントによって共通部分を再利用することができた 63 導入してよかった点

Slide 64

Slide 64 text

• データの変更があった際の画面への反映が簡単 • 導入前:JS側でデータ変更→画面側に反映させる処理 が必要 • 導入後:JS側でデータ変更→自動で画面側に反映される • コードが読みやすくなった • データ処理と表示処理が分離されている • データ処理の内部でも処理が用途に分かれている (computed, method, filtersなど) • コンポーネントによって共通部分を再利用することができた 64 導入してよかった点

Slide 65

Slide 65 text

• データの変更があった際の画面への反映が簡単 • 導入前:JS側でデータ変更→画面側に反映させる処理 が必要 • 導入後:JS側でデータ変更→自動で画面側に反映される • コードが読みやすくなった • データ処理と表示処理が分離されている • データ処理の内部でも処理が用途に分かれている (computed, method, filtersなど) • コンポーネントによって共通部分を再利用することができた 65 導入してよかった点

Slide 66

Slide 66 text

• データの変更があった際の画面への反映が簡単 • 導入前:JS側でデータ変更→画面側に反映させる処理 が必要 • 導入後:JS側でデータ変更→自動で画面側に反映される • コードが読みやすくなった • データ処理と表示処理が分離されている • データ処理の内部でも処理が用途に分かれている (computed, method, filtersなど) • コンポーネントによって共通部分を再利用することができた 66 導入してよかった点

Slide 67

Slide 67 text

• データの変更があった際の画面への反映が簡単 • 導入前:JS側でデータ変更→画面側に反映させる処理 が必要 • 導入後:JS側でデータ変更→自動で画面側に反映される! • コードが読みやすくなった • データ処理と表示処理が分離されている • データ処理の内部でも処理が用途に分かれている (computed, method など) • コンポーネントによって共通部分を再利用することができた 67 導入してよかった点 仕様の変更や修正にも強いコードになった

Slide 68

Slide 68 text

• 導入直後のコードのリファクタリング • 導入直後コードはVue.jsの恩恵を受けきれていない • まだまだVue.jsで記述できる箇所がある • 共通部分をまとめる • 現状:ページ単位で共通処理がまとまっている • 今後:ページを跨いで共通部分をまとめる • グラフのコンポーネント など 68 今後やりたいこと

Slide 69

Slide 69 text

一緒に働くメンバーを募集しています!