官网基本做好了,接下来开始做核心组件

返回阅读列表点击 这里

目录准备

在项目 src 目录下创建 lib 文件夹,用来存放所有的核心组件吧。然后再在 lib 文件夹下创建 Button.vue 文件。

您也可以进行结构化设计,比如,这里就不进行了。

|-lib
|-Button
|- Button.vue
|- Button.ts
|_ Button.scss

需求分析

惯例先行需求分析

  1. 多种类基础 Button,包含警告、成功、危险等
  2. 允许设置 Button 为禁用状态
  3. 不止有传统 Button,还可以有文字或链接形式
  4. 当处于加载中,Button 应当显示
  5. 有不同的尺寸可供选择
  6. 应当允许更换颜色
  7. 当鼠标放置于 Button 上、鼠标按下未松开、处于加载中等状态时,应当变更背景色
  8. 允许用户自定义 Button 上显示的文本

那么可以整理出以下参数表格

参数 含义 类型 可选值 默认值
level 默认类型 string default / plain / primary / success / info / warning / danger default
disabled 是否禁用 boolean false / true false
theme 式样 string button / link / text button
loding 是否加载中 boolean false / true false
size 尺寸 string middle / small / large middle
color 颜色 string 任意合法颜色值 #f3678e

第 7 条,可以通过设置一个遮罩层来实现,只要遮罩层变色,背景色也等效变色

第 8 条,可以通过插槽实现,注意 vue3 不建议使用具名插槽

骨架

容易得到如下骨架

<template>
<button
class="jeremy-button"
:theme="theme"
:level="level"
:size="size"
:style="{ '--color': color }"
:disabled="disabled"
:loading="loading"
>
<div class="jeremy-button-mask"></div>
<span class="jeremy-button-loadingIndicator" v-if="loading"></span>
<slot></slot>
</button>
</template>

首先,本质应当是一个 button 元素,在此基础上,将参数列表中整理出来的每个参数,都使用 v-bind 绑定到 button

注意,此处绑定 color,必须是如上例一样,绑定到 --color 属性上,才可以在 css 中使用 css3 语法 var() 读取,在 css 小节会再解释,此处略

之后,在 button

  1. 放置一个遮罩层,用于变色
  2. 放置一个”加载中”的动画,用于在加载中状态下显示
  3. 放置一个默认插槽,用于传递用户自定义的文本

然后为上述元素配置各自的 class 名称,骨架就完成了。

功能

显然,参数列表中整理出来的内容,一定来自引用该组件的地方的传入,先根据参数列表,写好 ts 声明:

declare const props: {
theme?: "button" | "link" | "text";
level?:
| "default"
| "plain"
| "primary"
| "success"
| "info"
| "warning"
| "danger";
size?: "middle" | "small" | "large";
color: string;
disabled: boolean;
loading: boolean;
};

然后在 export default 中,写入我们的参数

export default {
install: function (Vue) {
Vue.component(this.name, this);
},
name: "JeremyButton",
props: {
theme: {
type: String,
default: "button",
},
level: {
type: String,
default: "default",
},
size: {
type: String,
default: "middle",
},
color: {
type: String,
default: "#8c6fef",
},
disabled: {
type: Boolean,
default: false,
},
loading: {
type: Boolean,
default: false,
},
},
};

对于事件绑定,因为我们设计的组件只有一个唯一的根元素,所以对于外部传递过来的事件,会自动绑定到组件的根元素上面。

样式表

注意 :UI 库的样式表一般不要加 scoped 修饰符,为了尽可能减少对用户样式表的影响,方便用户 DIY

特别注意 : button 元素会有默认黑色外边框,不属于 border,必须通过 outline: none; 才能消除

然后,我们使用 css3var() 语法,取得我们通过 ts 绑定到 style 上的 --color 属性

为什么是 --color 而不是 color ?因为 var() 语法要求这个参数必须是 -- 开头,才可以正常访问到

对于遮罩层,采用淡出到白色即可实现,原理此处不解释了

最后,对于多种不同的 button,可以使用 scss 提供的 mixin / include 语法来实现,完整代码如下:

$theme-color: var(--color);
$base-mask: fade-out(#fff, 0.7);
$active-mask: fade-out(#fff, 0.5);
$h: 32px;
$radius: 4px; @keyframes jeremy-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.jeremy-button {
position: relative;
display: inline-block;
padding: 10px 16px;
color: white;
border-radius: $radius;
border: none;
font-size: 16px;
cursor: pointer;
white-space: nowrap;
transition: background-color 250ms;
outline: none;
:focus {
outline: none;
}
> .jeremy-button-mask {
position: absolute;
display: inline-block;
height: 100%;
width: 100%;
left: 0;
top: 0;
border-radius: $radius;
&:hover {
background: $base-mask;
}
}
&[loading="true"],
&[disabled] {
cursor: not-allowed;
> .jeremy-button-mask {
pointer-events: none;
}
}
> .jeremy-button-loadingIndicator {
width: 14px;
height: 14px;
display: inline-block;
margin-right: 4px;
border-radius: 8px;
border-style: solid;
border-width: 2px;
animation: jeremy-spin 1s infinite linear;
}
} @mixin layout($color) {
$loading-color: fade-out(black, 0.7); background: $color; &:active {
> .jeremy-button-mask {
background: $active-mask;
}
}
> .jeremy-button-loadingIndicator {
border-color: $loading-color $loading-color $loading-color transparent;
}
&[loading="true"],
&[disabled] {
> .jeremy-button-mask {
background: $base-mask;
}
}
}
.jeremy-button[theme="button"] {
$color: $theme-color; @include layout($color);
}
.jeremy-button:not([theme="button"]) {
padding: 0;
background: white;
color: black;
&:hover {
color: $theme-color;
}
}
.jeremy-button[theme="link"] {
text-decoration: underline;
}
.jeremy-button[level="plain"] {
$base-color: $theme-color;
@include layout(white);
color: black;
> .jeremy-button-mask {
border: 1px solid rgb(187, 187, 187);
} &:not([loading="true"]):not([disabled]) {
&:hover {
> .jeremy-button-mask {
border: 1px solid $base-color;
}
color: $base-color;
}
}
}
.jeremy-button[level="primary"] {
$color: #29adfa; @include layout($color);
}
.jeremy-button[level="success"] {
$color: rgb(103, 194, 58); @include layout($color);
}
.jeremy-button[level="info"] {
$color: #808080; @include layout($color);
}
.jeremy-button[level="warning"] {
$color: rgb(230, 162, 60); @include layout($color);
}
.jeremy-button[level="danger"] {
$color: rgb(245, 108, 108); @include layout($color);
}
.jeremy-button[size="large"] {
padding: 14px 24px;
}
.jeremy-button[size="small"] {
padding: 6px 10px;
}

以上,button 组件就完成了! :happy:

测试一下

感谢阅读

05 - Vue3 UI Framework - Button 组件的更多相关文章

  1. 06 - Vue3 UI Framework - Dialog 组件

    做完按钮之后,我们应该了解了遮罩层的概念,接下来我们来做 Dialog 组件! 返回阅读列表点击 这里 需求分析 默认是不可见的,在用户触发某个动作后变为可见 自带白板卡片,分为上中下三个区域,分别放 ...

  2. 10 - Vue3 UI Framework - Tabs 组件

    标签页是非常常用的组件,接下来我们来制作一个简单的 Tabs 组件 返回阅读列表点击 这里 需求分析 我们先做一个简单的需求分析 可以选择标签页排列的方向 选中的标签页应当有下划线高亮显示 切换选中时 ...

  3. 08 - Vue3 UI Framework - Input 组件

    接下来再做一个常用的组件 - input 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 input 组件有两种类型,即 input 和 textarea 类型 当类型为 ...

  4. 09 - Vue3 UI Framework - Table 组件

    接下来做个自定义的表格组件,即 table 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 基于原生 table 标签的强语义 允许用户自定义表头.表体 可选是否具有边框 ...

  5. 11 - Vue3 UI Framework - Card 组件

    卡片是非常常用也是非常重要的组件,特别是在移动端的众多应用场景中,随便打开一个手机 App ,您会发现充斥着各种各样的卡片. 所以,我们也来制作一个简易的 Card 组件 返回阅读列表点击 这里 需求 ...

  6. 00 - Vue3 UI Framework - 阅读辅助列表

    阅读列表 01 - Vue3 UI Framework - 开始 02 - Vue3 UI Framework - 顶部边栏 03 - Vue3 UI Framework - 首页 04 - Vue3 ...

  7. 07- Vue3 UI Framework - Switch 组件

    为了更好的提升用户体验,我们这里再做一个很常用的开关组件 switch 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 switch 组件应分为选中/未被选中,两种状态 可以通过 ...

  8. 04 - Vue3 UI Framework - 文档页

    官网的首页做完了,接下来开始做官网的文档页 返回阅读列表点击 这里 路由设计 先想想我们需要文档页通向哪些地方,这里直接给出我的设计: 所属 子标题 跳转路径 文件名(*.vue) 指南 介绍 /do ...

  9. 01 - Vue3 UI Framework - 开始

    写在前面 一年多没写过博客了,工作.生活逐渐磨平了棱角. 写代码容易,写博客难,坚持写高水平的技术博客更难. 技术控决定慢慢拾起这份坚持,用作技术学习的阶段性总结. 返回阅读列表点击 这里 开始 大前 ...

随机推荐

  1. java更开源-安全可靠国产系统背景下的应有.NET Core的一席之地

    "安可"背景下的中国软件开发 在中美当前背景下的安全可靠国产系统(简称安可),安可产业要实现技术自主可控,需要在四个层面逐步实现:基础硬件设施,如芯片.服务器.存储.交换机.路由器 ...

  2. 直播预告 | 猪齿鱼V1.1发布,线上新功能详解邀您参加

    2021年11月11日,数智化效能平台猪齿鱼 Choerodon发布 V1.1版本,多项功能新增或优化,多管齐下,全面提升团队工作效能! 通过提供体系化方法论和协作.测试.DevOps及容器工具,猪齿 ...

  3. 【BugFix】K8S节点NOT READY状态,错误信息:network plugin is not ready: cni config uninitialized

    错误现象 runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: netw ...

  4. CVPR 之 老照片修复

    周末闲来无事,随手整理电脑里的照片,望着一张物是人非的老相片,勾起了斑驳的回忆.忽尔转念一想,何不 PS 下,但 PhotoShop 有些大且不免费自己懒得装,于是,转向免费的图像复原软件. 网上搜来 ...

  5. [bzoj1107]驾驶考试

    转化题意,如果一个点k符合条件,当且仅当k能到达1和n考虑如果l和r($l<r$)符合条件,容易证明那么[l,r]的所有点都将会符合条件,因此答案是一个区间枚举答案区间[l,r],考虑如何判定答 ...

  6. html+css第七篇-表格

    表格标签: table 表格 thead 表格头 tbody 表格主体 tfoot 表格尾 tr 表格行 th 元素定义表头 td 元素定义表格单元 表格样式重置 table{border-colla ...

  7. 计算机系统->Hello World的一生 | 程序如何运行

    2021年11月27日准备发在基地微信公众号上的推文. 综合了多篇大佬的博客,以及自己已经知道的知识,对一些疑惑进行了现阶段我认为还算满意的解答. 不过又产生了很多疑问: 内存和磁盘的关系 CPU是如 ...

  8. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  9. Small but Funny Tricks [Remember them all!]

    模数 1e9 的神奇求行列式: #include <bits/stdc++.h> using namespace std; const int maxn = 1e2, mod = 1e9; ...

  10. 解决Package is not available (for R version XXX)?

    目录 1. 更新R(不推荐) 2. 更改或指定镜像源 3.源码安装 安装R包时这个错误是经常见到的.我认为有几个方法可解决,记录之. 1. 更新R(不推荐) 简单粗暴的方法就是更新R,但这波及的范围太 ...