<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Milad Alizadeh</title>
    <description>The latest articles on DEV Community by Milad Alizadeh (@miladalizadeh).</description>
    <link>https://dev.to/miladalizadeh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F109319%2Fa9990859-43cc-4cfb-aadf-bdf7fa4fe0bb.jpeg</url>
      <title>DEV Community: Milad Alizadeh</title>
      <link>https://dev.to/miladalizadeh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miladalizadeh"/>
    <language>en</language>
    <item>
      <title>Vue CLI 3.0 plugin for creating apps using Atomic Design &amp; Storybook</title>
      <dc:creator>Milad Alizadeh</dc:creator>
      <pubDate>Mon, 22 Oct 2018 12:01:26 +0000</pubDate>
      <link>https://dev.to/miladalizadeh/vue-cli-30-plugin-for-creating-apps-using-atomic-design--storybook-42dk</link>
      <guid>https://dev.to/miladalizadeh/vue-cli-30-plugin-for-creating-apps-using-atomic-design--storybook-42dk</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/milad-alizadeh/vue-cli-plugin-atomic-design"&gt;Vue Atomic Design Plugin&lt;/a&gt; is an opinionated Vue CLI 3 plugin that follows Atomic Design methodology. Please refer to this &lt;a href="http://bradfrost.com/blog/post/atomic-web-design/"&gt;fantastic article written&lt;/a&gt; by Brad Frost for more information.&lt;/p&gt;

&lt;p&gt;related projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/milad-alizadeh/vue-cli-plugin-atomic-design-components"&gt;vue-cli-plugin-atomic-design-component&lt;/a&gt; - A library of Vue components based on Atomic Design&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/milad-alizadeh/vue-cli-plugin-scss-base"&gt;vue-cli-plugin-scss-base&lt;/a&gt; - A starter SCSS base for Vue projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to install
&lt;/h2&gt;

&lt;p&gt;You first need to install Vue Cli 3&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @vue/cli
# OR
yarn global add @vue/cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then you can add the plugin by typing the following command&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vue add atomic-design

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Storybook
&lt;/h2&gt;

&lt;p&gt;Vue Atomic Design uses &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; as its design system tool. Originally created for React, Storybook is tool for creating UI Components in isolation. The advantage of using Storybook is that we can create our style guide and our project at the very same time without maintaining both which is great for both small and large scale applications.&lt;br&gt;
Once you install the plugin the storybook will be configured and you can use it by running:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;yarn run serve:storybook&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;or generate a static style guide:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;yarn run build:storybook&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;Atomic design has a very clean approach in grouping components through composition which is a a great combination with Vue.js&lt;/p&gt;

&lt;p&gt;The summary of Atomic Design structure is as Follows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atoms
&lt;/h3&gt;

&lt;p&gt;An atom is a native html tag. A Vue components that renders only one tag such as  &lt;code&gt;div&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt; or any other.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// atoms/Button.vue

&amp;lt;template&amp;gt;
  &amp;lt;button class="a-button" @click="$emit('click')"&amp;gt;
    &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
  &amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// atoms/Input.vue

&amp;lt;template&amp;gt;
  &amp;lt;input class="a-input" type="text" v-model="value" @input="$emit('input') /&amp;gt;
&amp;lt;/template&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Molecule
&lt;/h3&gt;

&lt;p&gt;A molecule is a combination of two or several atoms.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// molecules/SearchForm.vue

&amp;lt;template&amp;gt;
  &amp;lt;form class="m-search-form"&amp;gt;
    &amp;lt;Input @input="handleInput"/&amp;gt;
    &amp;lt;Button @click="handleSearch"&amp;gt;Search&amp;lt;/Button&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Organisms
&lt;/h3&gt;

&lt;p&gt;An organism is a combination of atoms, molecules and other organisms&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// organsims/Header.vue

&amp;lt;template&amp;gt;
  &amp;lt;header class="o-header"&amp;gt;
    &amp;lt;Logo /&amp;gt;
    &amp;lt;Navigation /&amp;gt;
    &amp;lt;SearchForm /&amp;gt;
  &amp;lt;/header&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Templates
&lt;/h3&gt;

&lt;p&gt;A combination of organisms, molecules and atoms to form a complete page. Templates only have dummy placeholder content.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// templates/PageTemplate.vue

&amp;lt;template&amp;gt;
  &amp;lt;div class="o-page-template"&amp;gt;
    &amp;lt;Hero /&amp;gt;
    &amp;lt;Posts /&amp;gt;
    &amp;lt;Comments /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;Pages are essentially instances of templates with real representative content. This is generally the point where Vuex connects to our templates. The benefit of this approach is the separation of data and UI and it enables you to create your UI regardless of where your data actually comes from. This also makes the testing much easier.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/PostPage.vue

&amp;lt;template&amp;gt;
  &amp;lt;PageTemplate
    :posts="posts"
    :hero="hero"
    :comments="comments"
  /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import { mapState } from 'vuex'

export default {
  computed: {
    mapState({
      posts: state =&amp;gt; state.posts.postList,
      hero: state =&amp;gt; state.home.hero,
      comments: state =&amp;gt; state.comments.commentList,
    })
  }
}
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Folder Structure
&lt;/h3&gt;

&lt;p&gt;In order to make organisation simpler, each component has a folder with its name which has 3 files in it. &lt;code&gt;index.vue&lt;/code&gt;, &lt;code&gt;index.stories.js&lt;/code&gt; and &lt;code&gt;index.test.js&lt;/code&gt;. With this structure all the tests, stories and the component will be in the same place without clutter. For example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- components
   -- atoms
      -- Button
         -- index.vue
         -- index.stories.js
         -- index.test.js
      -- Input
         -- index.vue
         -- index.stories.js
         -- index.test.js
   -- molecules
      -- SearchInput
         -- index.vue
         -- index.stories.js
         -- index.test.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With following this structure all of the stories will be created on runtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  Storybook
&lt;/h4&gt;

&lt;p&gt;Can you categories storybook stories by naming the story module to '{Category} - {Component Name}'. For example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;storiesOf('Atom - Button', module)
  .add('default', () =&amp;gt; ({
    components: { Button },
    template: `
      &amp;lt;Button /&amp;gt;
    `
  }));

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Vuex
&lt;/h4&gt;

&lt;p&gt;This plugin takes a &lt;a href="https://vuex.vuejs.org/guide/modules.html"&gt;modular&lt;/a&gt; approach to organising Vuex store. Each feature of your app is seperated into a module which include its own state, mutations, actions and getters. For example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- storeModules
   -- Posts
     -- index.js
   -- Users
     -- index.js
   -- Users
     -- index.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For example storeModules/users/index.js will contain the following:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const state = {
  userList: [],
  currentUser: null
}

const mutations = {
  setUsers (state, payload) {
    state.userList = payload
  },

  setCurrentUsers (state, payload) {
    state.currentUser = payload
  }
}

const actions = {
  async getUsers ({ commit }, username) {
    let response = await fetch(`//api.github.com/users`)
    let users = await response.json()
    commit('setUsers', users)
  }
}

export default {
  state,
  mutations,
  actions
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;you can then reference this module in your app like:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    {{ $store.state.users.userList }}
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
  created() {
     $store.dispatch('users/getUsers');
  }
&amp;lt;script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You only need to create the folders under &lt;code&gt;storeModule&lt;/code&gt; folder and the folder name will be used as namespaced. You do not need to import these modules into your store manually as it's done automatically with Webpack.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>atomicdesign</category>
      <category>storybook</category>
    </item>
  </channel>
</rss>
