| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- <template>
- <text class="cl-icon" :class="[ptClassName]" :style="iconStyle" :key="cache.key">
- {{ icon.text }}
- </text>
- </template>
- <script setup lang="ts">
- import { computed, type PropType } from "vue";
- import {
- forInObject,
- get,
- has,
- parsePt,
- useCache,
- isDark,
- ctx,
- hasTextColor,
- isNull
- } from "@/cool";
- import { icons } from "@/icons";
- import { useSize } from "../../hooks";
- defineOptions({
- name: "cl-icon"
- });
- // 定义组件属性
- const props = defineProps({
- // 透传样式
- pt: {
- type: Object,
- default: () => ({})
- },
- // 图标名称
- name: {
- type: String,
- default: ""
- },
- // 图标大小
- size: {
- type: [String, Number] as PropType<string | number>,
- default: 32
- },
- // 图标高度
- height: {
- type: [String, Number] as PropType<string | number>,
- default: null
- },
- // 图标宽度
- width: {
- type: [String, Number] as PropType<string | number>,
- default: null
- },
- // 图标颜色
- color: {
- type: String,
- default: ""
- }
- });
- // 透传样式类型定义
- type PassThrough = {
- className?: string;
- };
- // 解析透传样式
- const pt = computed(() => parsePt<PassThrough>(props.pt));
- // 缓存
- const { cache } = useCache(() => [props.color]);
- // 字号
- const { getRpx, ptClassName } = useSize(() => pt.value.className ?? "");
- // 图标类型定义
- type Icon = {
- font: string; // 字体名称
- text: string; // 图标文本
- };
- // 图标信息
- const icon = computed<Icon>(() => {
- let font = "";
- let text = "";
- try {
- let code = "";
- // 遍历字体库查找对应图标
- forInObject(icons, (value, key) => {
- if (has(value, props.name)) {
- font = key;
- code = get(value, props.name) as string;
- }
- });
- text = String.fromCharCode(parseInt(code, 16));
- } catch (e) {
- console.error(`图标 ${props.name} 不存在`, e);
- }
- return {
- font,
- text
- };
- });
- // 图标颜色
- const color = computed(() => {
- if (props.color != "" && !isNull(props.color)) {
- switch (props.color) {
- case "primary":
- return ctx.color["primary-500"] as string;
- case "success":
- return "#22c55e";
- case "warn":
- return "#eab308";
- case "error":
- return "#ef4444";
- case "info":
- return ctx.color["surface-500"] as string;
- case "dark":
- return ctx.color["surface-700"] as string;
- case "light":
- return ctx.color["surface-50"] as string;
- case "disabled":
- return ctx.color["surface-300"] as string;
- default:
- return props.color;
- }
- }
- return isDark.value ? "white" : (ctx.color["surface-700"] as string);
- });
- // 图标样式
- const iconStyle = computed(() => {
- const style = {};
- // 判断是不是有颜色样式
- if (!hasTextColor(ptClassName.value)) {
- style["color"] = color.value;
- }
- // 设置字体
- if (icon.value.font != "") {
- style["fontFamily"] = icon.value.font;
- }
- // 设置字体大小
- style["fontSize"] = getRpx(props.size!);
- // 设置高度
- style["height"] = getRpx(props.height ?? props.size!);
- style["lineHeight"] = getRpx(props.size!);
- // 设置宽度
- style["width"] = getRpx(props.width ?? props.size!);
- return style;
- });
- </script>
|