如何在 Vue.js 中引入原子设计?
本文为翻译文章,原文链接:
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。通过遵循其原则,您可以创建可重用、模块化和可扩展的组件,使您的代码更易于维护,用户更满意。
扩展链接:
如何在 Vue.js 中引入原子设计?的更多相关文章
- 如何在vue项目中引入elementUI组件
个人博客同步文章 https://mr-houzi.com/2018/02/... 前提:已经安装好Vue 初始化vue vue init webpack itemname 运行初始化demo 运行一 ...
- vue.js中引入图片
vue中引入图片 前言:vue中引入图片时,会显示不出来,除非在css中引入.而在template中或者js动态引入时,会显示不出图片. 解决一 图片通过后端返回引入网络图片路径即可. <div ...
- 详解如何在vue项目中引入饿了么elementUI组件
在开发的过程之中,我们也经常会使用到很多组件库:vue 常用ui组件库:https://blog.csdn.net/qq_36538012/article/details/82146649 今天具体说 ...
- 如何在Vue项目中引入jQuery?
假设你的项目由vue-cli初始化 (e.g. vue init webpack my-project). 在你的vue项目目录下执行: npm install jquery --save-dev 打 ...
- 如何在vue项目中引入element-ui
安装 elementUI npm install element-ui --save 引入elementUI import ElementUI from 'element-ui' import 'el ...
- 如何在vue项目中引入阿里巴巴的iconfont图库
1. 打开 http://www.iconfont.cn/ 2. 选择我们喜欢的图标,点击上面的小车,加入图标库,即右侧的购物车 3.点击购物车,点击下载代码 4.解压下载的文件夹,将文件夹复制到 a ...
- vue.js中引入其他文件export的方法:
import {GetPosition} from '../../lib/utils' //找到 该方法的文件路径,然后 用{}拿到 该方法 var position =GetPosition(); ...
- vue项目中引入Sass
Sass作为目前成熟,稳定,强大的css扩展语言,让越来越多的前端工程师喜欢上它.下面介绍了如何在vue项目 中引入Sass. 首先在项目文件夹执行命令 npm install vue-cli -g, ...
- vue项目中引入animate.css和wow.js
本文转自:https://blog.csdn.net/liyunkun888/article/details/85003152 https://www.zhuimengzhu.com/content/ ...
- 如何在Vue项目中给路由跳转加上进度条
1.前言 在平常浏览网页时,我们会注意到在有的网站中,当点击页面中的链接进行路由跳转时,页面顶部会有一个进度条,用来标示页面跳转的进度(如下图所示).虽然实际用处不大,但是对用户来说,有个进度条会大大 ...
随机推荐
- WakaTime Readme Stats-开源项目翻译
寻找不同语言和地区的翻译 #23 Readme中添加了功能标志的开发指标 眼前一亮的Readme统计数据 你是早起的还是夜间的? 你一天中什么时候工作效率最高? 你用什么语言编写代码? 让我们在你的个 ...
- 【Docker】部署Tomcat
搜索镜像 $ docker search 镜像名称:镜像TAG # 如: 没有加TAG,表示默认搜索的是最新版本的tomcat镜像 $ docker search tomcat # 如:搜索 tomc ...
- BUUCTF-MISC-面具下的flag(vmdk的解压和Brainfuck与Ook解密)
准备工作 下载附件得到一个一张图片 丢入winhex,发现还有一个flag.vmdk文件 vmdk文件其实是虚拟机使用的硬盘文件 打开kali binwalk -e mianju.jpg 关键步骤 这 ...
- 2023ccpc大学生程序设计竞赛-wmh
这算是我第一次参加这种团队赛,感谢程老师给我这个机会.刚开赛还算比较顺利,一眼看出来A是个签到,拿下之后开始跟榜F题.一开始想法比较简单,就是排序,记录相邻两个数的差,然后再排序.wa了后以为是范围出 ...
- 行行AI人才直播第13期:刘红林律师《AIGC创业者4大法律问题需注意》
行行AI人才(海南行行智能科技有限公司)是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台. AIGC爆火至今,商业落地已成为各行各业焦点的问题.它的广泛应用也带来了一系列的法律风险和挑战.一 ...
- python3 使用位图排序
代码 from bitmap import BitMap a=[1,5,3,4,7,8,15,6,9] print(a) bm=BitMap(max(a)) #print(dir(bm)) print ...
- 2021-8-2 Mysql个人练习题
创建学生表 CREATE TABLE student( id int, uname VARCHAR(20), chinese FLOAT, english FLOAT, math FLOAT ); I ...
- failed (2: No such file or directory) in /var/www/QQ_Music/nginx.conf:18
错误原因 解决方案 引入文件 /www/server/nginx/conf/mime.types;
- 面霸的自我修养:JMM与锁的理论
王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是<面霸的自我修养>的第二弹,内容是 Java 并发编程中关于 Java 内存模型(Ja ...
- 时序数据库 InfluxDB 第一篇 安装部署
使用场景: 最近项目上遇到大数据存储的问题,一个IOT融合项目,涉及到大量的工控监测数据存储.当前存储到关系库中的数据已经达到2亿条了.做了很多优化,查询还是很慢.便想着是否有更好的解决方案. 了解到 ...