本文爲翻譯文章,原文鏈接:
https://medium.com/@9haroon_dev/introducing-atomic-design-in-vue-js-a9e873637a3e
前言
原子設計是一種創建設計系統的方法,它將用戶界面分解爲可重用的小組件,即:
- Atoms 原子
- Molecules 分子
- Organisms 生物體
- Templates 模板
- Pages 頁面
通過遵循模塊化設計方法,原子設計可幫助團隊創建一致、可縮放且可維護的 UI。
在這篇文章中,小編將探討如何在 Vue 中實現原子設計。下文將從 Atomic Design 的基礎知識開始,然後演示如何在 Vue.js 中應用其原理。
原子設計由五個級別組成,表示 UI 的構建基塊。對於此示例,小編創建了一個倒置樹結構,以可視化每個解剖結構的連接方式。
原子 Atoms
原子是 UI 的最小單元,無法在不失去其含義的情況下進一步分解。原子的示例包括圖標、按鈕、標籤、輸入和排版。
在 Vue.js 中,原子可以創建爲可重用的組件,這些組件接受 props 來自定義它們的外觀和行爲。
TextboxAtom
<template>
<div class="component-wrapper" data-name="textBoxAtom">
<label>{{ label }}: <input type="text" :placeholder="placeHolder" /></label>
</div>
</template>
<script>
export default {
name: 'TextBoxAtom',
props: {
label: {
type: String,
default: 'labelName'
},
placeHolder: String,
},
};
</script>
<style scoped>
input{
padding: 0.75em 2em;
}
</style>
ButtonAtom
<template>
<div class="component-wrapper" data-name="buttonAtom">
<button :disabled="disabled">
<slot>Button</slot>
</button>
</div>
</template>
<script>
export default {
name: 'ButtonAtom',
props: {
type: String,
size: String,
disabled: Boolean,
},
};
</script>
<style scoped>
button {
color: #4fc08d;
}
button {
background: none;
border: solid 1px;
border-radius: 2em;
font: inherit;
padding: 0.5em 2em;
}
</style>
LogoAtom
<template>
<div class="component-wrapper" data-name="logoAtom">
<img :src="computedImageUrl" alt="logo"/>
</div>
</template>
<script>
export default {
props: {
width: {
type: Number,
default: 50
},
height: {
type: Number,
default: 50
}
},
computed: {
computedImageUrl() {
return `https://picsum.photos/${this.width}/${this.height}`
}
}
};
</script>
分子 Molecules
分子是兩個或多個原子的組合,它們協同工作以執行特定功能。在 Vue.js 中,可以通過將原子組合爲父組件中的子組件來創建分子。分子的例子包括表單、搜索欄、導航菜單和卡片。
參考上面的例子,小編需要組合原子以創建以下分子:
SubscribeFormMoecule
<template>
<form class="component-wrapper" data-name="subscribeFormMolecules">
<TextboxAtom label="Email" />
<ButtonAtom>Subscribe</ButtonAtom>
</form>
</template>
<script>
import TextboxAtom from "https://codepen.io/haroonth/pen/LYXgdKg.js";
import ButtonAtom from "https://codepen.io/haroonth/pen/BaGqrJg.js";
export default {
components: { ButtonAtom, TextboxAtom }
};
</script>
<style scoped>
form {
display: inline-flex;
}
</style>
SearchFormMoecule
<template>
<form class="component-wrapper" data-name="searchFormMolecules">
<InputAtom label="Search" />
<ButtonAtom>Search</ButtonAtom>
</form>
</template>
<script>
import InputAtom from "https://codepen.io/haroonth/pen/LYXgdKg.js";
import ButtonAtom from "https://codepen.io/haroonth/pen/BaGqrJg.js";
export default {
components: { ButtonAtom, InputAtom }
};
</script>
<style scoped>
form {
display: inline-flex;
}
</style>
Form Molecule
<template>
<div class="form-molecule component-wrapper" data-name="formMolecules">
<div><InputAtom :label="nameLabel" :placeholder="namePlaceholder" /></div>
<div><InputAtom :label="emailLabel" :placeholder="emailPlaceholder" /></div>
<p>
<ButtonAtom :disabled="isSubmitDisabled">
{{ submitLabel || "Button" }}
</ButtonAtom>
</p>
</div>
</template>
<script>
import InputAtom from "https://codepen.io/haroonth/pen/LYXgdKg.js";
import ButtonAtom from "https://codepen.io/haroonth/pen/BaGqrJg.js";
export default {
name: "FormMolecule",
components: {
InputAtom,
ButtonAtom
},
props: {
nameLabel: String,
namePlaceholder: String,
emailLabel: String,
emailPlaceholder: String,
submitLabel: String,
isSubmitDisabled: Boolean
}
};
</script>
Organisms
Organisms是形成 UI 不同部分的分子組合,例如頁眉、頁腳、側邊欄和內容塊。在 Vue.js 中,可以通過將分子組合爲佈局組件中的子組件來創建生物體。
本文中小編爲大家介紹三種Organisms
HeaderOrganism
<template>
<header class="component-wrapper" data-name="headerOrganism">
<LogoAtom width="60" />
<SearchFormMoecules />
</header>
</template>
<script>
import SearchFormMoecules from "https://codepen.io/haroonth/pen/zYMmjqa.js";
import LogoAtom from "https://codepen.io/haroonth/pen/xxQMbeJ.js";
export default {
components: { SearchFormMoecules, LogoAtom }
};
</script>
<style scoped>
header {
min-height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
ContentOrganism
<template>
<div class="page-organism">
<div class="content-wrapper-title">
<h1><slot name="title">Here might be a page title</slot></h1>
<p><slot name="description">Here might be a page description</slot></p>
</div>
<slot>...</slot>
<!-- This might includes some molecules or atoms -->
</div>
</template>
<script>
export default {
name: "ContentOrganism",
components: {}
};
</script>
<style scoped>
.page-organism {
padding-top: 50px;
padding-bottom: 80px;
box-shadow: inset 0px 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.content-wrapper-title {
text-align: center;
}
</style>
FooterOrganism
<template>
<footer class="component-wrapper" data-name="footerOrganism">
<CopyrightAtom />
<SubscribeFormMoecules />
</footer>
</template>
<script>
import SubscribeFormMoecules from "https://codepen.io/haroonth/pen/ExOrarL.js";
import LogoAtom from "https://codepen.io/haroonth/pen/xxQMbeJ.js";
import CopyrightAtom from "https://codepen.io/haroonth/pen/gOQqOBj.js";
export default {
components: { SubscribeFormMoecules, LogoAtom, CopyrightAtom }
};
</script>
<style scoped>
footer {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
模板 Templates
模板是通過指定生物在區域內的位置和大小(例如頁眉、頁腳和內容區域)來定義頁面佈局和組成的結構,下面是它的外觀:
<template>
<div class="full-layout-template">
<HeaderOrganism />
<ContentOrganism class="content">
<template #title>
<slot name="title">default title</slot>
</template>
<template #description>
<slot name="description">default description</slot>
</template>
<slot />
</ContentOrganism>
<FooterOrganism class="page-footer" />
</div>
</template>
<script>
import HeaderOrganism from "https://codepen.io/haroonth/pen/WNYaJGR.js";
import ContentOrganism from "https://codepen.io/haroonth/pen/vYQbOeO.js";
import FooterOrganism from "https://codepen.io/haroonth/pen/RwqvPRN.js";
export default {
name: "FullLayoutTemplate",
components: {
HeaderOrganism,
ContentOrganism,
FooterOrganism
}
};
</script>
<style scoped>
.full-layout-template {
display: flex;
flex-direction: column;
min-height: 90vh;
}
.content {
flex: 1 0 auto;
}
.page-footer {
flex-shrink: 0;
}
</style>
頁面 Pages
頁面是將模板與特定內容組合以形成完整視圖的 UI 的最終呈現形式。在原子設計中,頁面就像模板的實例,代表用戶的獨特體驗。
在 Vue.js 中,可以通過複製模板並將其插槽替換爲實際內容來創建頁面。雖然,在這個例子中,小編只更改內容有機體的內容,但您可以選擇更改所有內容或不更改任何內容。
<template>
<FullLayoutTemplate>
<template #title>{{ title }}</template>
<template #description>{{ description }}</template>
<div class="fixed-width">
<FormMolecule nameLabel="Name" emailLabel="Email" submitLabel="Save" />
</div>
</FullLayoutTemplate>
</template>
<script>
import FullLayoutTemplate from "https://codepen.io/haroonth/pen/GRwzpxx.js";
import FormMolecule from "https://codepen.io/haroonth/pen/PoxyRMo.js";
export default {
name: "HomePage",
components: {
FullLayoutTemplate,
FormMolecule
},
data() {
return {
title: "Welcome to my example",
description: "This is an example of Atomic Design in Vue.js",
copyright: "Copyright © 2023"
};
}
};
</script>
<style scoped>
* {
font-family: Avenir, Helvetica, Arial, sans-serif;
}
.fixed-width {
max-width: 350px;
margin: 0 auto;
}
</style>
總結:在 Vue.js 中原子設計的好處
通過在 Vue.js 中使用原子設計,你可以實現幾個好處,例如
- 一致性:通過創建可重用的組件,可以確保 UI 在所有頁面上的外觀和行爲一致。
- 可伸縮性:通過將 UI 分解爲小塊,可以輕鬆添加、刪除或更新組件,而不會影響系統的其他部分。
- 可維護性:通過將組件組織到文件夾和文件中,您可以輕鬆查找、編輯或調試它們,並與系統的其他部分隔離。
- 可重用性:通過創建獨立組件,您可以在其他項目中重用它們或與社區共享它們,從而節省時間和精力。
原子設計是一種強大的方法,可以幫助你在 Vue.js 中設計更好的 UI。通過遵循其原則,您可以創建可重用、模塊化和可擴展的組件,使您的代碼更易於維護,用戶更滿意。
擴展鏈接: