| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- <template>
- <text
- class="cl-icon"
- :class="[
- isDark ? 'text-white' : 'text-surface-700',
- {
- '!text-primary-500': color == 'primary',
- '!text-green-500': color == 'success',
- '!text-yellow-500': color == 'warn',
- '!text-red-500': color == 'error',
- '!text-surface-500': color == 'info',
- '!text-surface-700': color == 'dark',
- '!text-surface-50': color == 'light',
- '!text-surface-300': color == 'disabled'
- },
- pt.className
- ]"
- :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 } 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: ""
- }
- });
- // 缓存
- const { cache } = useCache(() => [props.color]);
- // 字号
- const { getRpx } = useSize();
- // 透传样式类型定义
- type PassThrough = {
- className?: string;
- };
- // 解析透传样式
- const pt = computed(() => parsePt<PassThrough>(props.pt));
- // 图标类型定义
- 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;
- }
- });
- // Android平台特殊处理
- // #ifdef APP-ANDROID
- // @ts-ignore
- text = new String(Character.toChars(parseInt(code, 16).toInt()));
- // #endif
- // 其他平台处理
- // #ifndef APP-ANDROID
- text = String.fromCharCode(parseInt(code, 16));
- // #endif
- } catch (e) {
- console.error(`图标 ${props.name} 不存在`, e);
- }
- return {
- font,
- text
- };
- });
- // 图标样式
- const iconStyle = computed(() => {
- const style = {};
- if (props.color != "") {
- style["color"] = props.color;
- }
- if (icon.value.font != "") {
- style["fontFamily"] = icon.value.font;
- }
- style["fontSize"] = getRpx(props.size!);
- style["height"] = getRpx(props.height ?? props.size!);
- style["width"] = getRpx(props.width ?? props.size!);
- style["lineHeight"] = getRpx(props.size!);
- return style;
- });
- </script>
|