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

本文爲翻譯文章,原文鏈接:
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" 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" />
    &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中集成報表插件

基於分支的版本管理,幫助低代碼從項目交付走向定製化產品開發

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章