如何在 Vue.js 中引入原子設計?

2023-10-23 15:03:42

本文為翻譯文章,原文連結:
https://medium.com/@9haroon_dev/introducing-atomic-design-in-vue-js-a9e873637a3e

前言

原子設計是一種建立設計系統的方法,它將使用者介面分解為可重用的小元件,即:

  1. Atoms 原子
  2. Molecules 分子
  3. Organisms 生物體
  4. Templates 模板
  5. 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">

<template>
  <form class="component-wrapper" data-name="subscribeFormMolecules">
    <TextboxAtom label="Email" />
    &nbsp;
    <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。通過遵循其原則,您可以建立可重用、模組化和可延伸的元件,使您的程式碼更易於維護,使用者更滿意。

擴充套件連結:

新手入門-在Vue框架中嵌入前端Excel表格外掛

新手入門 – 在Angular15中整合報表外掛

基於分支的版本管理,幫助低程式碼從專案交付走向客製化化產品開發