it's an endless world.

グロースをデザインするひと

Vue.js × Atomic Design 【Vue.js Advent Calendar 2017 5日目】

f:id:headless_pasta:20171201111833p:plain

この記事はVue.js #1 Advent Calendar 2017の5日目の記事です。
昨日はakifoさんのエラーをユーザーへ伝えるVue.jsコンポーネント作りましたの記事でした。


本日は私がAtomic Designの概念を用いてVue.jsのコンポーネントを組み立てるというお話をさせていただきたいと思います。

コンポーネントって何?どう使うの?

公式ドキュメントにも記されている通り、コンポーネントはVue.jsの最も強力な機能の1つです。

UI上の各要素をパーツ化し、それぞれのパーツの中にHTML(意味)・JavaScript(機能)・CSS(見た目)を含めることが可能です。
これにより再利用性も高まりますし、プロジェクトのリソースを整然と管理することが可能となります。

例えば、ヘッダーをコンポーネントとして使いたい場合。
次のようにMyHeader.vueを作成し、それを他のページ内に組み込むことでヘッダーをコンポーネントとして利用することができます。

MyHeader.vue

<template>
  <header>
    <img src="~/assets/logo.png" alt="にゃー">
    <navi>
      <a>top</a>
      <a>search></a>
      <a>mypage</a>
    </navi>
  </header>
</template>

<script>
export default {
  name: 'MyHeader',
  methods: {
    nya () {
      console.log('にゃー')
    }
  },
  created () {
    this.nya()
  }
}
</script>

<style scoped>
.header {
  background: #000;
  color: #FFF;
}
</style>

Top.vue

<template>
  <div class="main">
    <MyHeader></MyHeader>
  </div>
</template>

<script>
import MyHeader from './components/organisms/MyHeader'

export default {
  name: 'Top',
  components: {
    MyHeader
  }
}
</script>

<style scoped>
.main {
  padding: 20px;
}
</style>

コンポーネントをいかに設計すべきか?

さて、ここからが本題となります。

一言に「コンポーネント」と言っても、単一要素から複雑なページまでいろいろなものをコンポーネントとして利用することが可能です。

例えばプロジェクトの/src/components/直下にそれぞれのvueファイルを配置したとしてもその詳細度は様々であり、さらに複数の人間が開発に関わるプロジェクトだと容易にカオスってしまうことは想像に難くありません。
ソースコード全体の見通しを良くする」という目的で利用しているはずなのにこれでは本末転倒です。

では、どうすれば良いでしょうか?

そこに「何かしらのルール」を導入することが一番の解決策だと私は考えます。

そしてその「何かしらのルール」として最も適していると思っているのが次のAtomic Designという考え方です。

Atomic Designについて

Atomic Designでは、その名の通りページ内のすべての要素を「Atom(原子)」から始まる次の5つの要素に徹底的に分解して考えます。これらの要素を組み合わせてデザインしていく考え方が、Atomic Designです。

要素* 説明*
Atoms(原子) 要素の最小単位
Molecules(分子) Atomsを組み合わせて作成された要素
Organisms(有機体) AtomsやMoleculesを組み合わせて作成された要素
Templates(テンプレート) 複数のOrganismsが組み合わされた仮ページ、ワイヤーフレームになるもの
Pages(ページ) 複数のOrganismsが組み合わされたページ、最終的にユーザの目に映る1ページ

詳しい内容については、id:kubosho_ さんが書かれた次の記事が参考になりますのでご一読されることをオススメします。

https://blog.kubosho.com/entry/using-atomic-designblog.kubosho.com

ちょうど一昨日公開されていたこちらの資料もとてもわかりやすかったです。

speakerdeck.com

MoleculesやOrganismsの詳細度は人によって微妙に異なってしまう可能性もありますが、だいたいの認識はこれで合わせられるかと思います。

実際のディレクトリ例

例えば、こんな感じ。

  • src
    • App.vue
    • main.js
    • assets
    • components
      • Atoms
        • Link.vue
        • Logo.vue
      • Molecules
        • HeaderMenu.vue
        • Notice.vue
      • Organisms
        • Header.vue
        • UserProfile.vue
      • Pages
        • Top.vue
        • Account.vue

Nuxt.jsを利用している場合はpagesは既に別にされているのでこのような感じになりますね。

  • pages
  • components
    • Atoms
    • Molecules
    • Organisms

ちなみに、どのコンポーネントでどのコンポーネントが利用されているのかをMindMapに残しておくことで、プロジェクトメンバー感での効率はさらに上がります。

f:id:headless_pasta:20171201122231p:plain

まとめ

ここまで読んでくださったのになんですが、この記事は私が夏に書いたこの記事の焼きまし版だったりします。

employment.en-japan.com

あまりお行儀が良くないとわかりつつ書きました。

ただ、あらためてvue.jsに焦点にすえてこのことを書くことでAtomic Designの概念でコンポーネントを切ることがvue.jsのデファクトスタンダードになってほしいという願いがあります。


vue.jsを利用される際にコンポーネントの切り方で迷ったときは、ぜひ一度試していただければ幸いです。

明日の記事

明日はsh-ogawaさんの記事です。

www.slideshare.net