1 of 37

アットコスメのブランドマーケティングシステムにVuexを導入した話

2020.2.25 Roppongi.vue #5 LT

@y_okasuke @sakaguchii

2 of 37

自己紹介

名前: 岡下幸生

所属: テクノロジー本部BIDソリューション開発部

担当: エンジニア

業務: PHP(Laravel)/Go/Js/Docker/AWS.. いろいろ

趣味: DJ機材いじり、 openFrameworksいじり、youtube(最近はパーカーチャンネルにはまってます)

3 of 37

自己紹介

名前:坂口一華

所属:テクノロジー本部デザイン部

担当:フロントエンドエンジニア(マークアップ多め)

デザイナーさんとのやりとりがとても多いです

趣味:リングフィット・フィットネスボクシング

ハリネズミを眺めること

4 of 37

株式会社アイスタイル

Market Design Company

「Beauty × IT で世界No.1企業へ」というMissionを掲げ、

  • BtoC
  • BtoBtoC
  • 小売
  • EC

などなど化粧品を中心としたBeautyを想起させる市場のあらゆるポイントに携わるサービスを展開しています。

5 of 37

6 of 37

Vuexを導入したプロジェクト(今回話す話)

・マーケティングシステム「ブランドオフィシャル」というサービス

・主に化粧品ブランドがマーケティング分析に活用

7 of 37

ブランドオフィシャルとは

・2018/3 サービスリリース

 商品を購入したユーザーの傾向、ブランドさんが投稿した記事の分析 …etc

2020/01 新機能リリース ← Vuex導入

 商品やコンテンツに接触したユーザーデータの分析画面

 ユーザーの行動を絞り込み、接触した商品情報等を表示する機能

8 of 37

What is a brand official - dashboard

コンテンツに接触したユーザーデータを可視化

9 of 37

What is a brand official - analysis

ユーザーの行動をさらに絞り込む

分析画面

10 of 37

ユーザーの行動を

絞り込む分析画面…?🤔

11 of 37

デフォルトで

選択されている

条件だと26人

12 of 37

「ユーザーの行動」と

「行動に関連する商品」を

選択することで

該当するユーザを絞り込む

13 of 37

開発期間

・7月〜10月 仕様・要望を調整しつつひたすら開発

・11月 単体テスト期間

・12月 サービステスト期間

14 of 37

Vuexを選んだ理由

(1) 新画面ということで新しい技術の選定

(2) APIにて頻繁にデータを取得・更新

(3) APIレスポンスのデータ形式が微妙に異なる、表示する項目が多く、

  表示レイアウト形式も非常に複雑

15 of 37

Vuexを選んだ理由

(4) リアルタイムで絞り込みかつ可視化が必要→ストアの機能を十全に活かせることができるのでは…

(5) Vue.js使ったことある人が多い

16 of 37

どうのようにVuexを学習したか

・基礎から学ぶ Vue.js mio著

・Vue.js + Vuexでデータが循環する全体像を図解してみた

https://qiita.com/m_mitsuhide/items/f16d988ec491b7800ace

・vuex example https://github.com/vuejs/vuex/tree/dev/examples

17 of 37

プロジェクト構成に関して...

18 of 37

プロジェクト構成-1

components配下

vueコンポーネント、APIクライアント、エンティティ、Store、各種モジュール類

appディレクトリ配下

Laravel(blade.php)にて読み込むjsファイル類

config配下 定数を定義したモジュール

util配下ユーティリティクラス

19 of 37

プロジェクト構成-2(components配下)

APIクライアント

ファクトリークラス

エンティティオブジェクトを作成

entities配下

企画側と認識を合わせた、このプロジェクトの

共通言語(ドメインモデル)が定義されたクラスファイル類

20 of 37

プロジェクト構成-3

Storeディレクトリ配下

エンティティをStore(state)に保持し状態を管理

トップレベルのVueコンポーネント

21 of 37

実装に関して...

22 of 37

実装に関して-1

blade.php側からのdata属性をpropsで子コンポーネントに流し込む

DOM読み込み完了

画面に必要なトップレベルのVueインスタンスを生成

※プロジェクト構成-1のappディレクトリ配下

23 of 37

実装に関して-2

受け取ったjsonをファクトリーを介してエンティティへ

※プロジェクト構成-2のAPIクライアント

24 of 37

実装に関して-3

Store(state)データを操作するjs

(getters,mutations,actions実装)

※プロジェクト構成-3のStoreディレクトリ配下

25 of 37

Store(state)のデータに対する操作

actionsにてAPIクライアントを呼びだし、mutations内のメソッドにてStateを変更しcommit

26 of 37

画面操作からState更新までの流れ

storeのactions内のメソッドを呼び出す

27 of 37

基本的にはVuexのデータ循環通りに

28 of 37

表示について、

どのようにコンポーネントを切ったか 🔪

29 of 37

ダッシュボード固有のパーツ。固有のパーツのためおおきく切り出ししています 🔪

30 of 37

商品の個別パーツ。

「商品画像」「商品名」「評価点」「コメント数」「順位」の要素が

共通していたため、このボックスをひとつのコンポーネントとして切りました 🔪

31 of 37

記事のパーツ。

情報構造(ブログ・商品情報・クチコミ)や、デザインの構造から

再利用性を考えてコンポーネントをわけました 🔪

32 of 37

Issue

Atomic Designが意識できなかった😢

 ・コンポーネントを切るとき「UIとして再利用しやすいか」よりどちらかというと「作業分担がしやすいか」に重きをおいてファイルをわけてしまった

→ 知見・経験の少なさから、コンポーネントとしての「あるべき」が見えていなかった

→ 要件定義・マークアップと並行してデザインが進んでいたため(!)、UIとして「最小のパーツ」が見極められなかった

⇒ 今なお答えは出ていないので、「あるべき」は模索していきたい

33 of 37

Issue

CSSのコンポーネント化が出来なかった😢

 ・CSSは画面単位でファイルを作成、読み込むようにした

 → 結果、自己完結するコンポーネントにならなかった

 → ただし、vue-loaderはコンポーネント内に記述されたcssの順番を担保しないため、vue-loaderのバージョンが変わり、cssの順番が入れ替わった時確認が必要(スコープがちゃんとしていれば大丈夫とはいえ、確認しないままリリースは出来ない。。)

 ⇒ これもベストプラクティスは模索中

34 of 37

Issue

保守性を高くする

・現在 jasmin、karumaを使用している→Vue Test Utils、Jest導入

・TypeScript導入

35 of 37

What was good

・画面の関心事をエンティティとして取り扱い、Storeで管理することにより

複雑な画面の状態変化に対応することができた。

・仕様変更にも柔軟に対応できた。

・今後の要望にて柔軟にカスタマイズができそう。

36 of 37

まとめ

・求めている要件・実装したい機能をかなえるためにVueを選んだことは正解だった👍

vuexの導入実績解除、要件によって他のプロジェクトでも導入していける手応えを感じました👍

37 of 37

ご清聴ありがとうございました😄