アットコスメのブランドマーケティングシステムにVuexを導入した話
2020.2.25 Roppongi.vue #5 LT
@y_okasuke @sakaguchii
自己紹介
名前: 岡下幸生
所属: テクノロジー本部BIDソリューション開発部
担当: エンジニア
業務: PHP(Laravel)/Go/Js/Docker/AWS.. いろいろ
趣味: DJ機材いじり、 openFrameworksいじり、youtube(最近はパーカーチャンネルにはまってます)
自己紹介
名前:坂口一華
所属:テクノロジー本部デザイン部
担当:フロントエンドエンジニア(マークアップ多め)
デザイナーさんとのやりとりがとても多いです
趣味:リングフィット・フィットネスボクシング
ハリネズミを眺めること
株式会社アイスタイル
Market Design Company
「Beauty × IT で世界No.1企業へ」というMissionを掲げ、
などなど化粧品を中心としたBeautyを想起させる市場のあらゆるポイントに携わるサービスを展開しています。
Vuexを導入したプロジェクト(今回話す話)
・マーケティングシステム「ブランドオフィシャル」というサービス
・主に化粧品ブランドがマーケティング分析に活用
ブランドオフィシャルとは
・2018/3 サービスリリース
商品を購入したユーザーの傾向、ブランドさんが投稿した記事の分析 …etc
・2020/01 新機能リリース ← Vuex導入
商品やコンテンツに接触したユーザーデータの分析画面
ユーザーの行動を絞り込み、接触した商品情報等を表示する機能
What is a brand official - dashboard
コンテンツに接触したユーザーデータを可視化
What is a brand official - analysis
ユーザーの行動をさらに絞り込む
分析画面
ユーザーの行動を
絞り込む分析画面…?🤔
デフォルトで
選択されている
条件だと26人
「ユーザーの行動」と
「行動に関連する商品」を
選択することで
該当するユーザを絞り込む
開発期間
・7月〜10月 仕様・要望を調整しつつひたすら開発
・11月 単体テスト期間
・12月 サービステスト期間
Vuexを選んだ理由
(1) 新画面ということで新しい技術の選定
(2) APIにて頻繁にデータを取得・更新
(3) APIレスポンスのデータ形式が微妙に異なる、表示する項目が多く、
表示レイアウト形式も非常に複雑
Vuexを選んだ理由
(4) リアルタイムで絞り込みかつ可視化が必要→ストアの機能を十全に活かせることができるのでは…
(5) Vue.js使ったことある人が多い
どうのようにVuexを学習したか
・基礎から学ぶ Vue.js mio著
・Vue.js + Vuexでデータが循環する全体像を図解してみた
https://qiita.com/m_mitsuhide/items/f16d988ec491b7800ace
・vuex example https://github.com/vuejs/vuex/tree/dev/examples
プロジェクト構成に関して...
プロジェクト構成-1
components配下
vueコンポーネント、APIクライアント、エンティティ、Store、各種モジュール類
appディレクトリ配下
Laravel(blade.php)にて読み込むjsファイル類
config配下 定数を定義したモジュール
util配下ユーティリティクラス
プロジェクト構成-2(components配下)
APIクライアント
ファクトリークラス
エンティティオブジェクトを作成
entities配下
企画側と認識を合わせた、このプロジェクトの
共通言語(ドメインモデル)が定義されたクラスファイル類
プロジェクト構成-3
Storeディレクトリ配下
エンティティをStore(state)に保持し状態を管理
トップレベルのVueコンポーネント
実装に関して...
実装に関して-1
blade.php側からのdata属性をpropsで子コンポーネントに流し込む
DOM読み込み完了
画面に必要なトップレベルのVueインスタンスを生成
※プロジェクト構成-1のappディレクトリ配下
実装に関して-2
受け取ったjsonをファクトリーを介してエンティティへ
※プロジェクト構成-2のAPIクライアント
実装に関して-3
Store(state)データを操作するjs
(getters,mutations,actions実装)
※プロジェクト構成-3のStoreディレクトリ配下
Store(state)のデータに対する操作
actionsにてAPIクライアントを呼びだし、mutations内のメソッドにてStateを変更しcommit
画面操作からState更新までの流れ
storeのactions内のメソッドを呼び出す
基本的にはVuexのデータ循環通りに
表示について、
どのようにコンポーネントを切ったか 🔪
ダッシュボード固有のパーツ。固有のパーツのためおおきく切り出ししています 🔪
商品の個別パーツ。
「商品画像」「商品名」「評価点」「コメント数」「順位」の要素が
共通していたため、このボックスをひとつのコンポーネントとして切りました 🔪
記事のパーツ。
情報構造(ブログ・商品情報・クチコミ)や、デザインの構造から
再利用性を考えてコンポーネントをわけました 🔪
Issue
Atomic Designが意識できなかった😢
・コンポーネントを切るとき「UIとして再利用しやすいか」よりどちらかというと「作業分担がしやすいか」に重きをおいてファイルをわけてしまった
→ 知見・経験の少なさから、コンポーネントとしての「あるべき」が見えていなかった
→ 要件定義・マークアップと並行してデザインが進んでいたため(!)、UIとして「最小のパーツ」が見極められなかった
⇒ 今なお答えは出ていないので、「あるべき」は模索していきたい
Issue
CSSのコンポーネント化が出来なかった😢
・CSSは画面単位でファイルを作成、読み込むようにした
→ 結果、自己完結するコンポーネントにならなかった
→ ただし、vue-loaderはコンポーネント内に記述されたcssの順番を担保しないため、vue-loaderのバージョンが変わり、cssの順番が入れ替わった時確認が必要(スコープがちゃんとしていれば大丈夫とはいえ、確認しないままリリースは出来ない。。)
⇒ これもベストプラクティスは模索中
Issue
保守性を高くする
・現在 jasmin、karumaを使用している→Vue Test Utils、Jest導入
・TypeScript導入
What was good
・画面の関心事をエンティティとして取り扱い、Storeで管理することにより
複雑な画面の状態変化に対応することができた。
・仕様変更にも柔軟に対応できた。
・今後の要望にて柔軟にカスタマイズができそう。
まとめ
・求めている要件・実装したい機能をかなえるためにVueを選んだことは正解だった👍
・vuexの導入実績解除、要件によって他のプロジェクトでも導入していける手応えを感じました👍
ご清聴ありがとうございました😄