JavaScript
Vue.js
AtomicDesign
nuxt.js

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


開発環境

Nuxt.js v2

Express v4

bootstrap v4 (bootstrap-vue)


Atomic Designとは

Atomic Design はデザインシステムを作るための1つの手段

ざっくり言うと、UI コンポーネントの粒度をカテゴリーに明確に分ける手法

http://atomicdesign.bradfrost.com/

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

https://www.indetail.co.jp/blog/10234/


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のサンプルコードの詳細説明があります。