# 图标

项目中有以下多种图标使用方式。

## 组件库图标

使用 `ant-design-vue` 提供的图标

```vue
<template>
  <StarOutlined />
  <StarFilled />
  <StarTwoTone twoToneColor="#eb2f96" />
</template>

<script>
  import { defineComponent } from 'vue';
  import { StarOutlined, StarFilled, StarTwoTone } from '@ant-design/icons-vue';
  export default defineComponent({
    components: { StarOutlined, StarFilled, StarTwoTone },
  });
</script>
```

## Svg Sprite 图标

### 使用

将需要的 svg 图标放到`src/assets/icons`内

例: test.svg

1. 使用`SvgIcon`组件进行展示

```vue
<template>
  <SvgIcon name="test" />
</template>

<script>
  import { defineComponent } from 'vue';
  import { SvgIcon } from '/@/components/Icon';
  export default defineComponent({
    components: { SvgIcon },
  });
</script>
```

2. 使用`SvgIcon`组件进行展示

```vue
<template>
  <SvgIcon icon="test" />
</template>

<script setup lang="ts">
  import { SvgIcon } from '@eciol/ant-ui';
</script>
```

## Iconify 图标

使用方式请参考 [Icon 组件](../components/icon.md)

项目中使用到的是 [vite-plugin-purge-icons](https://github.com/antfu/purge-icons/blob/main/packages/vite-plugin-purge-icons/README.md) 这个插件来进行图标实现。

1. 安装依赖

```bash

yarn add @iconify/iconify

yarn add @iconify/json @purge-icons/generated -D

```

2. 在 `vite.config.ts`内引入插件

```ts
import PurgeIcons from 'vite-plugin-purge-icons';

export default {
  plugins: [PurgeIcons()],
};
```

3. 编写 Icon 组件

完整代码 [/packages/ui/share-ui/src/icon/index.vue](http://192.168.9.192/eci-frontend/base-framework/-/blob/main/packages/ui/share-ui/src/icon/index.vue)

```vue
<script setup lang="ts">
  import { Icon } from '@iconify/vue';
  // import iconify from '@iconify/iconify';
  import { isString } from '@eciol/shared';
  import type { CSSProperties } from 'vue';
  import { computed, useCssModule } from 'vue';

  defineOptions({
    name: 'VbenIcon',
    inheritAttrs: false,
  });

  interface Props {
    /**
     * @description 图标名
     */
    icon: string;

    /**
     * @description 图标颜色
     * @default ''
     */
    color?: string;

    /**
     * @description 图标大小
     * @default 16
     */
    size?: number | string;

    /**
     * @description 图标集空间名
     * @default ''
     */
    namespace?: string;

    /**
     * @description 是否可悬浮
     * @default false
     */
    hoverable: boolean,
  }

  const props = withDefaults(defineProps<Props>(), {
    size: 16,
    namespace: '',
    color: '',
    hoverable: false,
  });

  const $style = useCssModule();

  // const iconRef = ref<HTMLSpanElement>();

  const iconName = computed(() => {
    const { namespace, icon } = props;
    return `${namespace ? namespace + ':' : ''}${icon}`;
  });

  const iconStyles = computed((): CSSProperties => {
    const { size, color } = props;
    return {
      fontSize: isString(size) ? `${Number.parseInt(size)}px` : `${size}px`,
      color,
      display: 'inline-flex',
    };
  });
</script>

<template>
  <Icon v-bind="$attrs" :class="[$style.icon, hoverable && '$style.hover', 'anticon']" :style="iconStyles" :icon="iconName" />
</template>

<style module scoped>
  .icon {
    display: inline-block;
  }

  .hover {
    &:hover {
      color: var(--primary-color);
      cursor: pointer;
    }
  }

  .iconify {
    display: block;
    min-width: 1em;
    min-height: 1em;
    background-color: #5551;
    border-radius: 100%;
  }
</style>

```
