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