LoginSignup
108

More than 3 years have passed since last update.

posted at

updated at

AtomicDesignをVue.js(Nuxt.js)に使うと最高な開発を体験できた

開発環境

Nuxt.js v2
Express v4
bootstrap v4 (bootstrap-vue)

Atomic Designとは

Atomic Design はデザインシステムを作るための1つの手段
ざっくり言うと、UI コンポーネントの粒度をカテゴリーに明確に分ける手法

Atomic Designの詳細については割愛しますので、下記サイトをご参照ください。

Nuxt.jsとAtomic Designの開発が最高なポイント

Nuxt.jsの機能:
routerなど面倒な設定を特に意識しないで実装できとても楽!

生産性向上 & 一貫性:
コンポーネントの独立性が高く、さらにVuexを使うとデータの操作とビューの表示が依存性低く、仕様変更に柔軟に対応できる
デザイン変更が発生する際、一箇所を修正するだけで、全てが適用される(これが一番好きなポイント)

もちろん、それぞれのページの対応のものもありますが、そもそもデザインや機能が違うものを共通の原子にすると、実装が複雑になってくる。
設計の問題になりますが、個人的には原子の機能を簡単にする方が使いやすいと思う

フォルダー構造

components
|
|---- atoms
|------ |---Album.vue
|------ |---BackBtn.vue
|---- molecules
|------ |---AlbumList.vue
|------ |---CommentList.vue
|---- organisms
|------ |---AlbumBook.vue
|---- page
|------ |---AlbumBooks.vue

atoms(原子)

ボタンなどのUI上の最小単位をatomsに分ける
このUIを例とすると、中にはlinkとimgとtitleだけのもの

<template>
  <div>
    <nuxt-link to="/album">
      <img class="album-image" :src="album.coverUrl" />
    </nuxt-link>
    <div>
      {{ album.title }}
    </div>
  </div>
</template>

<script>
export default {
  name: 'Album', // ここは外部をコンポーネントとして呼ぶ名前になる

  props: {
    album: {
      type: Object,
      required: true,
      default: null
    }
  }
}
</script>

<style scoped>
.album-image {  /* この原子のcssのみで設定する、うっかりオーバーライドしてほかのcssに影響することも減少できる */
  height: 175px;
  width: 175px;
  object-fit: cover;
  border-radius: 10px;
  margin: 1px;
}
</style>

molecules(分子)

原子を複数持つものなど
僕の場合は原子の親となる配列やオブジェクトにする

<template>
  <b-row>
    <b-col v-for="album in albums" :key="album.id">
      <Album :album="album"></Album>  <!-- 原子の個体 propsでデータを受け取る -->
    </b-col>
  </b-row>
</template>

<script>
import Album from '~/components/atoms/Album.vue'  // 原子をimport

export default {
  name: 'AlbumList', // この分子の外部を呼ぶ際の名前

  components: {
    Album // 原子をcomponentとして使う宣言
  },

  props: {
    data: {
      type: Object,
      required: true,
      default: () => null
    }
  }
}
</script>

organisms(生体)

複数分子をよく組み合わせたもの

<template>
  <section>
    <nav class="navbar navbar-light bg-light">
      <BackBtn path="/activity"></BackBtn>
    </nav>
    <div class="container-fluid">
      <AlbumList :data="albums"></AlbumList>
      <CommentList :comments="comments"></CommentList>
    </div>
  </section>
</template>

<script>
import BackBtn from '~/components/atoms/BackBtn.vue'
import CommentList from '~/components/molecules/CommentList.vue'
import AlbumList from '~/components/molecules/AlbumList.vue'

export default {
  name: 'AlbumBook', // この分子の外部を呼ぶ際の名前
  components: {
    BackBtn,   // 原子も組み合わせられる
    CommentList, // 別の分子
    AlbumList    // 複数アルバム原子を持つ分子
  }
  data() {
    comments: [
       ... // 分子が必要なデータ
    ]
  },
  computed: {
    albums() {
      return this.$store.state.albums // 分子が必要なデータ、Vuexからアクセスするとしたら、生体でまとめるか、もしくは分子で取得するか、柔軟に変更できる
    }
  },
}
</script>

最後

Page(従来のメインとなるhtmlファイル)にそれぞれのコンポーネントでimportする、デザインにあわせて簡単に組み合わせられる、再利用性の高いコンテンツを実装できるようになった。

難しいところは、一見沢山のファイルを分割しないといけないし、コンポーネントは再利用性の高いものを見分けないといけない。
多少面倒だが、一度乗れたら後ほど開発が楽になるので、開発初期段階からするとおすすめです!
皆さんもぜひ一度チャレンジしてみてください!

追記(AtomicDesignに関連する本)

Atomic Design ~堅牢で使いやすいUIを効率良く設計する
https://www.amazon.co.jp/dp/477419705X/ref=cm_sw_em_r_mt_dp_U_okgQCb402V52T

Vue.js入門 基礎から実践アプリケーション開発まで
https://www.amazon.co.jp/dp/4297100916/ref=cm_sw_em_r_mt_dp_U_klgQCbDR7BN3X
9章からAtomicDesignのサンプルコードの詳細説明があります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
108