序言
在上一篇文章中,我们成功搭建起 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 const
export 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
- 基于 Vue3 + Element-plus + websocket 即时聊天系统
- 基于 node 开发的后端服务:https://github.com/gmingchen/node-server