欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 【Nova UI】九、打造组件库第一个组件-图标组件(中):属性、功能与样式的完美融合

【Nova UI】九、打造组件库第一个组件-图标组件(中):属性、功能与样式的完美融合

2025/4/28 4:50:03 来源:https://blog.csdn.net/qq_40230003/article/details/147443006  浏览:    关键词:【Nova UI】九、打造组件库第一个组件-图标组件(中):属性、功能与样式的完美融合

序言

在上一篇文章中,我们成功搭建起 SVG 图标组件包的基础架构🏗️,这如同为组件库这座大厦奠定了稳固的基石。如今,我们将目光聚焦于图标组件样式的雕琢工作,思考如何巧妙运用已掌握的 SASS 全局变量管理技巧,赋予图标组件丰富多样且统一协调的外观风格🌈。这不仅是提升组件库视觉一致性的关键🔑,更是增强用户体验的重要一环。让我们一同开启这场图标组件的样式优化之旅🚶‍♂️。

Icon组件

在组件库的持续建设中,Icon 组件的开发是极为关键的一步🌟。为实现对图标组件属性及类型的精准把控,我们在packages/components/icon/src/目录下,新增了icon.tsicon.js文件。其中,icon.ts肩负着定义组件属性与 TypeScript 类型的重任。

icon.ts 剖析
import { ExtractPropTypes, PropType } from 'vue'
import { svgs } from '@nova-ui/svgs'export const iconProps = {name: {type: String as PropType<(typeof svgs)[number]>,required: true,},color: {type: String,},size: {type: [Number, String] as PropType<number | string>,},
} as constexport type IconType = ExtractPropTypes<typeof iconProps>

这段代码构建了 Icon 组件的基础属性体系📋。name属性指定图标名称,其取值限定在svgs数组内,确保只有预定义图标可被调用,避免非法名称的使用,就像给图标选择设置了一个 “白名单”🛂。color属性允许开发者通过字符串形式的颜色值对图标进行个性化上色🎨,轻松满足不同的视觉需求。size属性设计灵活,既支持数字形式(默认单位像素),也接受字符串形式的尺寸描述,满足不同场景下对图标大小的精确调整需求,无论是在小巧的移动端界面还是宽大的电脑屏幕上,都能完美适配📱🖥️。

PropType
是 Vue 中用于精确定义组件props类型的工具,通过它可指定复杂属性类型,增强 TypeScript 开发时的类型安全性。\

const MyComponent = defineComponent({props: {value: {type: [String, Number] as PropType<string | number>,required: false}},setup(props) {return () => <div>{props.value}</div>;}
});

在上述代码中,value属性可接受stringnumber类型的值,就像给组件的这个 “输入口” 明确了可接收的 “货物种类”🛒。

ExtractPropTypes
用于从props定义对象中提取属性类型信息,同样增强组件的类型安全性。\

const props = {message: {type: String,required: true}
};
const MessageComponent = defineComponent({props,setup(props) {return () => {return <div>{props.message}</div>;};}
});
type Props = ExtractPropTypes<typeof props/>;
const App = defineComponent({setup() {const myMessage = 'Hello, Vue 3!';return () => {return <MessageComponent message={myMessage} />;};}
});

在此例中,TypeScript依据ExtractPropTypes提取的Props类型,检查传递给MessageComponentmessage属性是否符合要求,确保数据传递的准确性和稳定性📡。

icon.vue 解析

icon.vue文件在 Icon 组件整体构建中,承担着实现具体功能的核心任务🧠。

<template><i:class="ns.b()":style="style"><component :is="svg" /></i>
</template>

在 template 里,<i> 标签作为图标容器,通过 :class 绑定 ns.b() 生成的特定类名,利用 useNamespace 避免样式冲突。:style 绑定 style 计算属性,用于动态调整图标样式。而 <component :is="svg" /> 依据 svg 计算属性,能动态渲染出对应 SVG 图标组件,增强了复用性与灵活性🎭。

<script lang="ts" setup>import { computed, CSSProperties } from 'vue'import { useNamespace } from '@nova-ui/hooks'import { isUndefined, addUnit } from '@nova-ui/utils'import * as Svgs from '@nova-ui/svgs'import { iconProps } from './icon'const ns = useNamespace('icon')defineOptions({name: 'NIcon',})const { name, color, size } = defineProps(iconProps)const svg = computed(() => {return Svgs[name]})const style = computed<CSSProperties>(() => {if (!color && !size) return {}return {fontSize: isUndefined(size) ? undefined : addUnit(size),color: color,}})
</script>

script部分,通过导入各种必要的模块与工具🛠️,为组件的功能实现提供了有力支持。computed用于创建计算属性,CSSProperties定义样式类型,useNamespace生成命名空间类名,isUndefinedaddUnit分别判断值是否为undefined及添加单位。同时,还导入了 SVG 图标组件与组件属性。

ns 通过 useNamespace 生成 Icon 组件的命名空间实例📍。defineOptions 定义组件名称为 NIcon。通过解构 defineProps(iconProps) 获取父组件传来的 namecolorsize 属性🍱。

svg 计算属性依据 name 从 Svgs 获取对应图标组件,style 计算属性根据 color 和 size 生成样式对象。若无这两个属性传入则返回空对象,否则为 size 添加单位并设置 fontSize 和 color 样式✨。

icon.vue 以简洁代码实现高效功能,为 Icon 组件在库中的应用与扩展筑牢根基。部分工具函数实现可在下方提及到的仓库中查看 。

样式

packages/theme-chalk/src目录下,新增icon.scss,用于编写 Icon 组件的样式。再在当前目录下新增index.scss统一导入所有组件样式。

@use 'mixins' as *;@include b(icon) {display: inline-flex;width: 1em;height: 1em;
}

这段样式代码为 Icon 组件设定了基础的展示样式,使其以inline-flex的布局方式呈现,宽度和高度均为1em,确保图标在页面上能够整齐、美观地展示🛍️。

到此,图标组件已经实现完成了🎉。通过从属性定义到功能实现,再到样式设计的一系列精心打造,我们成功地为组件库增添了一个实用且美观的 Icon 组件,为后续的开发工作奠定了更加坚实的基础。

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

感谢各位大侠一路相伴,实在感激! 不瞒您说,在下还有几个开源项目 📦,它们就像精心培育的幼苗 🌱,急需您的浇灌。要是您瞧着还不错,麻烦动动手指,给它们点亮几颗 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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词