DEV Community

J.Cho
J.Cho

Posted on

Using Atomic Design with Nuxt.js and have a great hacking time.

This is my first time write a english post.
I'm a web application developer working in Japan.And yes, I'm a Chinese.XD

What I used in this project

Nuxt.js v2.0
Express v4.0
bootstrap-vue v4.0

What is Atomic Design

In case you don't know what is Atomic Design.
Here are some good documents about it.

http://atomicdesign.bradfrost.com/
https://www.indetail.co.jp/blog/10234/

TL;Dr: It's a design system to show you how to create your UI component exactly you need to use.

How To Separate Your Folder

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

Atoms Samples

The smallest UI component in your project.
Like this. Just a nuxt-lint, div and img.

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

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

<style scoped>  <-- Use scoped to make the css only in this component
.album-image {
  height: 175px;
  width: 175px;
  object-fit: cover;
  border-radius: 10px;
  margin: 1px;
}
</style>

molecules

contain some atoms
In my case, I make it to be a array of the atoms

<template>
  <b-row>
    <b-col v-for="album in albums" :key="album.id">
      <Album :album="album"></Album>  <!-- use props in atom to receive the data -->
    </b-col>
  </b-row>
</template>

<script>
import Album from '~/components/atoms/Album.vue'  //  import the atom file

export default {
  components: {
    Album // This is the atom componet
  },

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

organisms

combine different molecules

<template>
  <section>
    <nav class="navbar navbar-light bg-light">
      <BackBtn path="/activity"></BackBtn>  <--- You can use atom aslo
    </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 { 
  components: {
    BackBtn, 
    CommentList, // different molecules
    AlbumList    // some molecules
  }
  data() {
    comments: [
       ... // 
    ]
  },
  computed: {
    albums() {
      return this.$store.state.albums // Using Vuex with Atomic Design is aslo a great idea, you can get your data in different ways.In your atom or your molecules.
    }
  },
}
</script>

Page

Finally, The page.
Make sure your page using less code you need.
If your page is larger you should think about to separate into small things like atom.

<template>
  <section>
    <AlbumBook></AlbumBook>
  </section>
</template>

<script>
import AlbumBook from '~/components/organisms/AlbumBook.vue'

export default {
  components: {
    AlbumBook
  }
}
</script>

At Last

Separate your files, decide which component should be smaller. Maybe is the most challenge thing in your project.
But once you get to the point. you'll get the benefit from it.
Especially in your early development stage.

1.Every time you want to change your component. You don't need to change them all.Just in one file.Any other your page import that file can be changed.

2.Easy for management.Less code you need, Less bugs.

P.S:
This post is what I wrote in my Qiita.(A Japanese Tech blog)
https://qiita.com/jakushin/items/e8b19f6a2c7bcd037573

Top comments (1)

Collapse
 
heriisei profile image
Heri Risnanto • Edited

Thank you!
ありがとう ございます!