序言
在上一篇文章中,我们成功搭建起 SVG 图标组件包的基础架构🏗️,这如同为组件库这座大厦奠定了稳固的基石。如今,我们将目光聚焦于图标组件样式的雕琢工作,思考如何巧妙运用已掌握的 SASS 全局变量管理技巧,赋予图标组件丰富多样且统一协调的外观风格🌈。这不仅是提升组件库视觉一致性的关键🔑,更是增强用户体验的重要一环。让我们一同开启这场图标组件的样式优化之旅🚶♂️。
Icon组件
在组件库的持续建设中,Icon 组件的开发是极为关键的一步🌟。为实现对图标组件属性及类型的精准把控,我们在packages/components/icon/src/
目录下,新增了icon.ts
和icon.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
属性可接受string
或number
类型的值,就像给组件的这个 “输入口” 明确了可接收的 “货物种类”🛒。
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
类型,检查传递给MessageComponent
的message
属性是否符合要求,确保数据传递的准确性和稳定性📡。
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
生成命名空间类名,isUndefined
和addUnit
分别判断值是否为undefined
及添加单位。同时,还导入了 SVG 图标组件与组件属性。
ns
通过 useNamespace
生成 Icon
组件的命名空间实例📍。defineOptions
定义组件名称为 NIcon
。通过解构 defineProps(iconProps)
获取父组件传来的 name
、color
、size
属性🍱。
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