Vue CLI plugin for Atomic Design which uses Storybook and a Modular Vuex approach
npm install vue-cli-plugin-atomic-designVue Atomic Design is an opinionated Vue CLI 3 plugin for using Atomic Design methodology with Vue.js.
Related projects:
* Vue Atomic Design Components - A library of Vue components based on Atomic Design
* Vue SCSS Base - A starter SCSS base for Vue projects
You first need to install Vue Cli 3
```
npm install -g @vue/cliOR
yarn global add @vue/cli
Then you can add the plugin by typing the following command
``
vue add atomic-design
`yarn run serve:storybook`
or to generate a static style guide:
`yarn run build:storybook`
The summary of Atomic Design structure is as Follows.
, p or any other.`
// atoms/VButton.vue
`
or`
// atoms/VInput.vue
`$3
A molecule is a combination of two or several atoms.
`
// molecules/VSearchForm.vue
`$3
An organism is a combination of atoms, molecules and other organisms
`
// organsims/Header.vue
`$3
A combination of organisms, molecules and atoms to form a complete page. Templates only have dummy placeholder content.`
// templates/VPageTemplate.vue
`$3
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.
`
// pages/VPostPage.vue
:posts="posts"
:hero="hero"
:comments="comments"
/>
`$3
It is highly recommended that all the filenames be prefixed with a base such as App or V. This prevents conflicts with existing and future HTML elements, since all HTML elements are a single word.
It is also recommended using namespaced class names and BEM for your CSS. The prefred format is 'componentTypeInitial-prefix-componentName'. For example Atom/VButton class name will a-v-button. This ensures any conflix with imported CSS frameworks and makes debugging easier.However you can scope your stying using other methods such as
scoped attribute, CSS modules or any other library/convention$3
In order to make organisation simpler, each component has a folder with its name which has 3 files in it.
index.vue, index.stories.js and index.test.js. With this structure the unit tests, stories and the component will be in the same place without clutter. For example:`
- components
- atoms
- VButton
- index.vue
- index.stories.js
- index.test.js
- VInput
- index.vue
- index.stories.js
- index.test.js
- molecules
- VSearchInput
- index.vue
- index.stories.js
- index.test.js
`With following this structure all of the stories will be created on runtime.
#### Storybook
Can you categories storybook stories by naming the story module to '{Category} - {Component Name}'. For example:
`
storiesOf('Atom - VButton', module)
.add('default', () => ({
components: { VButton },
template: ' '
}));`#### Unit Tests
Unit testing is an important part of any web project however it might require some setup and testing. Vue Atomic Design uses Jest as its testing tool. An example of a unit test for the
VButton components would be:`
import { mount } from '@vue/test-utils'
import VButton from '.'describe('Atom - VButton', () =>
test('Tag should be if href prop is set', () => {
const wrapper = mount(VButton, {
propsData: { href: 'http://google.com' }
})
expect(wrapper.contains('a')).toBe(true)
expect(wrapper.attributes().href).toBe('http://google.com')
})
})
`#### Vuex
This plugin takes a modular 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:
`
- storeModules
- posts
- index.js
- users
- index.js
`For example storeModules/users/index.js will contain the following:
`
const state = {
userList: []
}const mutations = {
setUsers (state, payload) {
state.userList = 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
}
`you can then reference this module in your app like:
`
{{ $store.state.users.userList }}