【Nova UI】十二、打造组件库之按钮组件(上):迈向功能构建的关键一步

序言

在上一篇文章中,我们深入探索了 icon 组件从测试到全局注册的全过程🎯,成功为其在项目中稳定运行筑牢了根基。此刻,组件库的建设之旅仍在继续,我们将目光聚焦于另一个关键组件 —— 按钮组件。按钮作为用户与界面交互的核心纽带🧐,其功能的完备性、样式的美观性以及操作的流畅性,都对用户体验起着至关重要的作用。接下来,让我们一同深入剖析按钮组件的实现过程,为组件库增添强大助力,使其在前端开发的舞台上绽放更加耀眼的光芒✨。

UI

我们先借鉴 Element Plus 组件库的样式,着手实现一个基础的按钮组件。参考图如下:

在这里插入图片描述

从图中可以分析出,该按钮具备defaultprimarysuccessinfowarningdanger这几种场景,它们的区别主要体现在边框颜色、字体颜色以及背景颜色上。结合我们的实际业务需求,我们开始打造自己的按钮组件

准备工作

按照惯例,我们首先在packages/components/button/src目录下,新增button.tsbutton.vue文件📄。

props属性

button.ts文件中,定义我们所需的props。这些属性包括场景、大小、是否禁用、是否处于加载中、加载时的图标、按钮的前缀图标、后缀图标、按钮形状以及按钮类型。

import { ExtractPropTypes, PropType } from 'vue'
import { useSceneProp, useSizeProp, useLoadingIconProp, useIconProp } from '@nova-ui/hooks'export const buttonShapes = ['round', 'circle'] as const
export type ButtonShapeType = typeof buttonShapes[number]export const buttonTypes = ['plain', 'text', 'link', 'dashed'] as const
export type ButtonTypeType = typeof buttonTypes[number]export const buttonProps = {scene: useSceneProp(),size: useSizeProp(),disabled: {type: Boolean,},loading: {type: Boolean,},loadingIcon: useLoadingIconProp(),prefixIcon: useIconProp(),suffixIcon: useIconProp(),shape: {type: String as PropType<ButtonShapeType>},type: {type: String as PropType<ButtonTypeType>}
} as constexport type ButtonType = ExtractPropTypes<typeof buttonProps>

相关代码如上述所示。其中,scene场景属性很可能在多个组件中复用,因此我们将其单独提取出来(这是一个良好的编程习惯,当相同代码在多处使用时,建议提取以提高代码的可维护性)。在packages/constants目录下新增scene.ts文件,用于存储场景的常量及其类型。同时,在packages/hooks/use-scene目录下新增index.ts文件,编写我们需要使用的props属性值。

// packages/constants/scene.ts
export const scenes = ['primary', 'success', 'warning', 'danger', 'error', 'info'] as const
export type Scene = typeof scenes[number]
// packages/hooks/use-scene/index.ts
import { PropType } from 'vue'
import { Scene } from '@nova-ui/constants'
export const useSceneProp = () => ({type: String as PropType<Scene>,
})

其它如sizeloadingIconprefixIconsuffixIcon等属性的提取方式与之类似,在此不再一一赘述。

模板部分:构建按钮的外观与交互结构

首先来看看这段代码的 HTML 模板部分,它决定了按钮在页面上的最终呈现效果,是按钮组件的 “外观设计师”👨‍🎨。

<template><button:class="[ns.b(),ns.m(scene),ns.m(size),ns.is('disabled', disabled),ns.is('loading', loading),ns.is(!shape, !!shape),ns.is(!type, !!type),]"><template v-if="loading"><slot v-if="$slots.loading" name="loading"></slot><NIcon v-else :class="ns.e('loading')" :name="loadingIcon"></NIcon></template><template v-if="$slots.prefix || prefixIcon"><slot v-if="$slots.prefix" name="prefix"></slot><NIcon v-else-if="prefixIcon" :class="ns.e('prefix')" :name="prefixIcon"></NIcon></template><slot></slot><template v-if="$slots.suffix || suffixIcon"><slot v-if="$slots.suffix" name="suffix"></slot><NIcon v-else-if="suffixIcon" :class="ns.e('suffix')" :name="suffixIcon"></NIcon></template></button>
</template>

这段模板代码定义了按钮组件的可视化结构与交互元素。最外层的<button>标签构建了按钮的基本框架,通过:class绑定一系列动态类名,实现按钮外观的多样化。

ns.b()提供了按钮的基础类名,是按钮样式的基石。ns.m(scene)ns.m(size)则根据传入的scene(场景)和size(尺寸)参数,为按钮添加相应的修饰类名,使按钮能够适配不同的使用场景与布局需求。

ns.is系列函数依据传入的布尔值属性,动态添加对应的状态类名。例如,ns.is('disabled', disabled)disabledtrue时,为按钮添加表示禁用状态的类名,改变按钮的外观以提示用户该按钮当前不可操作。同理,ns.is('loading', loading)根据loading状态添加或移除加载相关的类名,实现加载状态下按钮的视觉反馈。

在按钮内容方面,代码充分利用 Vue 的插槽机制与NIcon组件,实现了高度的灵活性。当按钮处于loading状态时,首先检查是否存在名为loading的插槽。若有,则渲染该插槽内容,允许开发者自定义加载状态下的显示元素;若没有,则渲染NIcon组件作为加载图标,图标类名由ns.e('loading')生成,图标名称则由loadingIcon属性指定。

对于按钮的前缀和后缀部分,同样采用了灵活的判断逻辑。先判断是否存在prefix插槽,若有则渲染插槽内容;若没有但设置了prefixIcon属性,则渲染NIcon组件作为前缀图标,类名由ns.e('prefix')生成,图标名称由prefixIcon指定。后缀部分的逻辑与之相同,通过这种方式,按钮可以轻松添加各种图标或自定义内容,极大地增强了按钮的功能性与美观性。

脚本部分:赋予组件功能与数据交互能力

脚本部分是按钮组件的核心,负责引入必要的模块、定义组件的配置与属性,如同为组件注入灵魂🧠。

<script lang="ts" setup>import { useNamespace } from '@nova-ui/hooks'import { buttonProps, ButtonType } from './button'import { NIcon } from '@nova-ui/components'const ns = useNamespace('button')defineOptions({name: 'NButton',})defineProps(buttonProps)
</script>

useNamespace函数用于生成具有统一规范的类名,确保按钮组件的样式管理清晰且易于维护。buttonPropsButtonType./button文件引入,其中buttonProps定义了按钮组件可接收的外部属性,如disabledloadingsize等,为组件与外部的数据交互提供了接口。

NIcon组件从@nova-ui/components引入,用于在按钮中显示各种图标。通过const ns = useNamespace('button')创建了按钮组件专属的样式命名空间实例,供模板部分生成类名使用。

defineOptions({name: 'NButton'})为按钮组件定义了名称NButton,方便在 Vue 项目中进行识别与引用。defineProps(buttonProps)则依据buttonProps定义了组件可接收的属性,将外部传入的数据与组件内部逻辑连接起来,使组件能够根据不同的属性值呈现出相应的状态与外观。

综上所述,这段代码通过模板与脚本的协同工作,实现了一个功能丰富、可定制性强的 Vue 按钮组件。它不仅能够满足各种常见的按钮使用场景,还为开发者提供了灵活的扩展空间,在前端组件库中具有重要的应用价值 。

🦀🦀感谢看官看到这里,如果觉得文章不错的话🙌,点个关注不迷路⭐。
诚邀您加入我的微信技术交流群🎉,群里都是志同道合的开发者👨‍💻,大家能一起交流分享摸鱼🐟。期待与您在群里相见🚀,咱们携手在开发路上共同进步✨ !
👉点我

感谢各位大侠一路相伴,实在感激! 不瞒您说,在下还有几个开源项目 📦,它们就像精心培育的幼苗 🌱,急需您的浇灌。要是您瞧着还不错,麻烦动动手指,给它们点亮几颗 Star ⭐,您的支持就是它们成长的最大动力,在此谢过各位大侠啦!

  • Nova UI组件库:https://github.com/gmingchen/nova-ui
  • 基于 Vue3 + Element-plus 管理后台基础功能框架
  • 预览:https://admin.gumingchen.icu
    • Github:https://github.com/gmingchen/agile-admin
    • Gitee:https://gitee.com/shychen/agile-admin
    • 基础版后端:https://github.com/gmingchen/java-spring-boot-admin
    • 文档:http://admin.gumingchen.icu/doc/
  • 基于 Vue3 + Element-plus + websocket 即时聊天系统
    • 预览:https://chatterbox.gumingchen.icu/
    • Github:https://github.com/gmingchen/chatterbox
    • Gitee:https://gitee.com/shychen/chatterbox
  • 基于 node 开发的后端服务:https://github.com/gmingchen/node-server

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/78693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙OSS文件(视频/图片)压缩上传组件-能够增删改查

一、鸿蒙实现处理-压缩上传整体代码处理逻辑 转沙箱压缩获取凭证并上传文件 文件准备&#xff08;拿到文件流&#xff09;获取上传凭证&#xff08;调接口1拿到file_name和upload_url&#xff09;执行文件上传&#xff08;向阶段2拿到的upload_url上传文件&#xff09;更新列表…

河道流量监测,雷达流量计赋能水安全智慧守护

在蜿蜒的河道之上&#xff0c;水流的脉搏始终与人类文明的兴衰紧密相连。从农田灌溉的水量调配到城市防洪的精准预警&#xff0c;从生态保护的水质溯源到水资源管理的决策&#xff0c;河道流量监测如同大地的 “血管检测”&#xff0c;是守护水安全的第一道防线。传统监测手段在…

CSS3 基础(边框效果)

一、边框效果 属性功能示例值说明border-radius创建圆角border-radius: 20px;设置元素的圆角半径&#xff0c;支持像素&#xff08;px&#xff09;或百分比&#xff08;%&#xff09;。值为 50% 时可变为圆形。box-shadow添加阴影box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.5)…

零基础小白如何上岸数模国奖

零基础小白如何上岸数模国奖 我自己本人第一次参加数模国赛顺利上岸国奖&#xff0c;当然那段经历也是比较痛苦了&#xff0c;差不多也是从当年四月开始接触数学建模&#xff0c;第一次参加妈妈杯成绩并不理想&#xff0c;后面不断参加数模比赛进行模拟&#xff0c;最后顺利上岸…

SQL学习-常用函数

常见SQL函数使用 &#xff08;注意&#xff1a;不同的数据库类型使用的语法不同&#xff09; 以下是MySQL和PostgreSQL在实现替换、抽取、拼接、分列四个常见字符串操作功能时的核心区别总结&#xff0c;按功能分类对比&#xff1a; 1. 替换&#xff08;Replace&#xff09; …

rt-linux下的cgroup cpu的死锁bug

一、背景 rt-linux系统有其非常大的实时性的优势&#xff0c;但是与之俱来的是该系统上有一些天然的缺陷。由于rt-linux系统允许进程在内核态执行的逻辑里&#xff0c;在持锁期间&#xff0c;甚至持spinlock锁期间&#xff0c;都能被其他进程抢占。这一特性能带来实时性的好处…

java—12 kafka

目录 一、消息队列的优缺点 二、常用MQ 1. Kafka 2. RocketMQ 3. RabbitMQ 4. ActiveMQ 5. ZeroMQ 6. MQ选型对比 适用场景——从公司基础建设力量角度出发 适用场景——从业务场景角度出发 四、基本概念和操作 1. kafka常用术语 2. kafka常用指令 3. 单播消息&a…

14【模块学习】74HC595:使用学习

74HC595 1、74HC595简介2、代码演示2.1、驱动8位流水灯 3、74HC595级联3.1、驱动16位流水灯3.2、驱动8位数码管3.3、驱动8x8点阵屏幕3.4、8x8点阵屏幕滚动显示 1、74HC595简介 在51单片机中IO引脚资源十分的紧缺&#xff0c;所以常常需要使用75HC595芯片进行驱动那些需要占用多…

JAVA后端开发常用的LINUX命令总结

一、Linux常用命令大全&#xff08;2025年最新版&#xff09; 常用 Linux 命令 文件和目录管理&#xff1a; cd&#xff1a;用于切换当前工作目录&#xff0c;如cd /home/user。mkdir&#xff1a;创建新目录&#xff0c;mkdir -p /home/user/mydir可递归创建多级目录。pwd&am…

uniapp-商城-40-shop 购物车 选好了 进行订单确认4 配送方式3 地址编辑

前面说了配送 和地址页面 当地址页面为空或需要添加地址时&#xff0c;需要添加地址。 我的地址页面有个按钮 就是添加地址 点击 添加地址 按钮 后&#xff0c;就会跳转到地址添加的页面 1、添加地址页面 2、添加地址文件夹以及文件的创建 3、添加地址的代码 <template…

现场问题排查-postgresql某表索引损坏导致指定数据无法更新影响卷宗材料上传

问题现象 今天突然被拉进一个群&#xff0c;说某地区友商推送编目结果报错&#xff0c;在我们自己的卷宗系统上传材料也一直转圈&#xff0c;也删除不了案件卷宗&#xff0c;重置模板也没用&#xff0c;只有个别案件有问题。虽然这事儿不属于我负责&#xff0c;但还是抽时间给…

Redis01-基础-入门

零、文章目录 Redis01-基础-入门 1、认识 NoSQL NoSQL 知识请参考&#xff1a;https://blog.csdn.net/liyou123456789/article/details/132612444 2、认识 Redis &#xff08;1&#xff09;简介 Redis&#xff08;Remote Dictionary Server&#xff0c;远程字典服务&…

【嘉立创EDA】如何在更新或转换原理图到PCB时,保留已有布局器件

文章路标👉 :one: 文章解决问题:two: 主题内容:three: 参考方法be end..1️⃣ 文章解决问题 操作环境:嘉立创EDA专业版 V2.2.37 本文使用嘉立创EDA,描述在更新或转换原理图到PCB时,保留已有布局器件的方法。本文将此过程记录,以供有需要的读者参考。 2️⃣ 主题内容 …

03 APQC PROCESS CLASSIFICATION FRAMEWORK (PCF)

APQC流程分类框架&#xff08;APQC Process Classification Framework, PCF&#xff09;最初由美国生产力与质量中心&#xff08;American Productivity & Quality Center, APQC&#xff09;开发&#xff0c;旨在用于跨组织的流程性能基准比较。现在&#xff0c;它也常被用…

分析型数据库入门指南:如何选择适合你的实时分析工具?

一、什么是分析型数据库&#xff1f;为什么需要它&#xff1f; 据Gartner最新报告显示&#xff0c;超过75%的企业现已在关键业务部门部署了专门的分析型数据库&#xff0c;这一比例还在持续增长。 随着数据量呈指数级增长&#xff0c;传统数据库已无法满足复杂分析场景的需求…

body Param Query 三个 不同的入参 分别是什么意思 在前端 要怎么传 这三种不同的参数

在 NestJS 中&#xff0c;Body()、Param() 和 Query() 用于处理不同类型的请求参数。以下是它们的含义及前端传递方式&#xff1a; Body()&#xff1a;请求体参数 • 含义&#xff1a;用于获取请求体中的数据&#xff08;如 POST/PUT 请求中提交的 JSON、表单数据等&#xff09…

神经网络(自己记录)

一、神经网络基础 5分钟-通俗易懂 - 神经网络 反向传播算法&#xff08;手算&#xff09;_哔哩哔哩_bilibili 二、GAT

Redis Slot 槽位分片具体案例

‌键值槽位分配案例‌ 当执行 SET {kaigejava}k1 v1 时&#xff0c;Redis 会提取 {} 内的有效部分 kaigejava&#xff0c;通过 CRC16 算法计算哈希值&#xff0c;再对 16384 取余得到槽位。例如&#xff1a; 若计算结果为 1495&#xff0c;则该键会被分配到槽位 1495 对应的节…

【多模态模型】跨模态智能的核心技术与应用实践

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现&#xff08;CLIP图像-文本检索&#xff09;运行结果验证 三、性能对比测试方法论量化数据对比结果…

final static 中是什么final static联合使用呢

final static 联合使用详解 final 和 static 在 Java 中经常一起使用&#xff0c;主要用来定义类级别的常量。这种组合具有两者的特性&#xff1a; 基本用法 public class Constants {// 典型的 final static 常量定义public static final double PI 3.141592653589793;pub…