Skip to content

QxsIcon

QxsIcon 是一个强大的通用图标组件,支持多种图标类型(Vue组件、Iconify、UnoCSS、CSS类、图片、SVG Sprite)和丰富的自定义功能,提供统一的图标使用体验。

基本用法

QxsIcon 组件支持多种图标类型,提供统一的使用体验。

属性

属性说明类型可选值默认值
icon图标名称或组件string | Component--
size图标大小number | string--
color图标颜色string--
flip翻转方向stringhorizontal / vertical / both / ''''
rotate旋转角度number-0
localIconPrefix本地图标前缀string-icon-
fallback图片加载失败时的备用图标string--
loading图片加载中显示的图标string--

支持的图标类型

QxsIcon 组件智能识别并支持以下图标类型:

1. Vue 组件图标

传入 Vue 组件对象,获得最佳性能和类型安全。

vue
<QxsIcon :icon="HomeComponent" />

2. Iconify 图标 (provider:name)

使用 Iconify 提供的海量在线图标库,格式为 集合名:图标名

vue
<QxsIcon icon="ep:home" />
<QxsIcon icon="mdi:home" />
<QxsIcon icon="lucide:user" />

3. UnoCSS 图标 (i-provider:name)

使用 UnoCSS 图标预设,编译时生成,零运行时开销。

vue
<QxsIcon icon="i-ep:home-filled" />
<QxsIcon icon="i-mdi:account" />
<QxsIcon icon="i-lucide:settings" />

4. CSS 类图标

支持多种 CSS 类图标格式:

自定义 CSS 类(i-开头)

vue
<QxsIcon icon="i-custom-home" />
<QxsIcon icon="i-custom-user" />

Font Awesome 图标

vue
<QxsIcon icon="fas fa-home" />
<QxsIcon icon="far fa-user" />
<QxsIcon icon="fab fa-github" />

Iconfont 图标

vue
<QxsIcon icon="iconfont icon-home" />
<QxsIcon icon="iconfont icon-user" />

其他 CSS 类图标

vue
<QxsIcon icon="material-icons">home</QxsIcon>
<QxsIcon icon="bootstrap-icons bi-house" />

5. 图片 URL

支持各种图片格式和路径。

vue
<QxsIcon icon="https://example.com/icon.png" />
<QxsIcon icon="/assets/icon.svg" />
<QxsIcon icon="./icon.png" />

6. SVG Sprite

使用 SVG 雪碧图,适合内部图标系统。

vue
<QxsIcon icon="home" />
<QxsIcon icon="user-profile" />

使用示例

基础用法

vue
<template>
  <div class="icon-demo">
    <!-- Vue 组件图标 -->
    <QxsIcon :icon="HomeComponent" />

    <!-- Iconify 图标 -->
    <QxsIcon icon="ep:home" />

    <!-- UnoCSS 图标 -->
    <QxsIcon icon="i-ep:home" />

    <!-- 图片 URL -->
    <QxsIcon
      icon="https://api.iconify.design/ep:home.svg"
      fallback="i-ep:picture"
      loading="i-ep:loading"
    />

    <!-- SVG Sprite -->
    <QxsIcon icon="home" />
  </div>
</template>

<script setup lang="ts">
import { QxsIcon } from '@qxs-bns/components'
import { Home as HomeComponent } from '@qxs-bns/icons'
</script>

样式定制

vue
<template>
  <div class="style-demo">
    <!-- 不同大小 -->
    <QxsIcon icon="ep:home" :size="16" />
    <QxsIcon icon="ep:home" :size="24" />
    <QxsIcon icon="ep:home" :size="32" />

    <!-- 不同颜色 -->
    <QxsIcon icon="ep:user" color="#409eff" />
    <QxsIcon icon="ep:user" color="#67c23a" />
    <QxsIcon icon="ep:user" color="#e6a23c" />

    <!-- 旋转 -->
    <QxsIcon icon="ep:arrow-right" :rotate="0" />
    <QxsIcon icon="ep:arrow-right" :rotate="90" />
    <QxsIcon icon="ep:arrow-right" :rotate="180" />

    <!-- 翻转 -->
    <QxsIcon icon="ep:arrow-right" flip="horizontal" />
    <QxsIcon icon="ep:arrow-right" flip="vertical" />
    <QxsIcon icon="ep:arrow-right" flip="both" />
  </div>
</template>

图片加载处理

vue
<template>
  <div class="image-demo">
    <!-- 带加载状态的图片图标 -->
    <QxsIcon
      icon="https://api.iconify.design/ep:home.svg"
      :size="32"
      fallback="i-ep:picture"
      loading="i-ep:loading"
    />

    <!-- 加载失败时显示备用图标 -->
    <QxsIcon
      icon="https://invalid-url.com/icon.png"
      :size="32"
      fallback="i-ep:picture"
      loading="i-ep:loading"
    />
  </div>
</template>

组合变换

vue
<template>
  <div class="transform-demo">
    <!-- 旋转 + 翻转 -->
    <QxsIcon
      icon="ep:arrow-right"
      :rotate="45"
      flip="horizontal"
      :size="24"
      color="#409eff"
    />

    <!-- 动态变换 -->
    <QxsIcon
      :icon="HomeComponent"
      :rotate="rotateAngle"
      :flip="flipDirection"
      :size="dynamicSize"
      :color="dynamicColor"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { QxsIcon } from '@qxs-bns/components'
import { Home as HomeComponent } from '@qxs-bns/icons'

const rotateAngle = ref(0)
const flipDirection = ref('')
const dynamicSize = ref(24)
const dynamicColor = ref('#409eff')
</script>

在按钮中使用

vue
<template>
  <div class="button-demo">
    <!-- 主要按钮 -->
    <el-button type="primary">
      <QxsIcon name="plus" :size="16" />
      新增
    </el-button>
    
    <!-- 危险按钮 -->
    <el-button type="danger">
      <QxsIcon name="delete" :size="16" />
      删除
    </el-button>
    
    <!-- 成功按钮 -->
    <el-button type="success">
      <QxsIcon name="check" :size="16" />
      确认
    </el-button>
    
    <!-- 警告按钮 -->
    <el-button type="warning">
      <QxsIcon name="warning" :size="16" />
      警告
    </el-button>
    
    <!-- 信息按钮 -->
    <el-button type="info">
      <QxsIcon name="info" :size="16" />
      信息
    </el-button>
  </div>
</template>

<script setup lang="ts">
import { QxsIcon } from '@qxs-bns/components'
</script>

<style scoped>
.button-demo {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.el-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
</style>

导航菜单

vue
<template>
  <nav class="nav-menu">
    <div class="nav-item" v-for="item in menuItems" :key="item.key">
      <QxsIcon :name="item.icon" :size="20" />
      <span>{{ item.label }}</span>
    </div>
  </nav>
</template>

<script setup lang="ts">
import { QxsIcon } from '@qxs-bns/components'

const menuItems = [
  { key: 'home', icon: 'home', label: '首页' },
  { key: 'user', icon: 'user', label: '用户管理' },
  { key: 'data', icon: 'chart', label: '数据统计' },
  { key: 'setting', icon: 'setting', label: '系统设置' },
  { key: 'help', icon: 'question', label: '帮助中心' }
]
</script>

<style scoped>
.nav-menu {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  background: #f5f7fa;
  border-radius: 8px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s;
  color: #606266;
}

.nav-item:hover {
  background: white;
  color: #409eff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>

状态图标

vue
<template>
  <div class="status-demo">
    <div class="status-item">
      <QxsIcon name="check-circle" color="#67c23a" :size="20" />
      <span>成功状态</span>
    </div>
    
    <div class="status-item">
      <QxsIcon name="warning-circle" color="#e6a23c" :size="20" />
      <span>警告状态</span>
    </div>
    
    <div class="status-item">
      <QxsIcon name="error-circle" color="#f56c6c" :size="20" />
      <span>错误状态</span>
    </div>
    
    <div class="status-item">
      <QxsIcon name="info-circle" color="#409eff" :size="20" />
      <span>信息状态</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { QxsIcon } from '@qxs-bns/components'
</script>

<style scoped>
.status-demo {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.status-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 4px;
  background: #f9f9f9;
}
</style>

自定义图标

vue
<template>
  <div class="custom-demo">
    <!-- 使用自定义 SVG -->
    <QxsIcon name="custom-logo" :size="32" />
    
    <!-- 使用插槽自定义 -->
    <QxsIcon :size="24">
      <svg viewBox="0 0 24 24" fill="currentColor">
        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
      </svg>
    </QxsIcon>
    
    <!-- 使用 Element Plus 图标 -->
    <QxsIcon type="component">
      <el-icon :size="24">
        <Star />
      </el-icon>
    </QxsIcon>
  </div>
</template>

<script setup lang="ts">
import { QxsIcon } from '@qxs-bns/components'
import { Star } from '@element-plus/icons-vue'
</script>

图标类型

SVG 图标(推荐)

vue
<template>
  <!-- 使用内置 SVG 图标 -->
  <QxsIcon name="home" type="svg" />
  <QxsIcon name="user" type="svg" />
  <QxsIcon name="setting" type="svg" />
</template>

字体图标

vue
<template>
  <!-- 使用字体图标 -->
  <QxsIcon name="home" type="font" />
  <QxsIcon name="user" type="font" />
</template>

<style>
/* 需要引入字体图标样式 */
@import '@qxs-bns/icons/font/iconfont.css';
</style>

组件图标

vue
<template>
  <!-- 使用 Vue 组件图标 -->
  <QxsIcon type="component">
    <HomeIcon />
  </QxsIcon>
</template>

<script setup lang="ts">
import { HomeIcon } from '@qxs-bns/icons'
</script>

样式定制

scss
.qxs-icon {
  // 基础样式
  display: inline-flex;
  align-items: center;
  justify-content: center;
  
  // 旋转动画
  &.spin {
    animation: qxs-icon-spin 1s linear infinite;
  }
  
  // 悬停效果
  &.hoverable {
    cursor: pointer;
    transition: all 0.3s;
    
    &:hover {
      transform: scale(1.1);
    }
  }
  
  // 不同尺寸
  &.size-small {
    width: 14px;
    height: 14px;
  }
  
  &.size-medium {
    width: 18px;
    height: 18px;
  }
  
  &.size-large {
    width: 22px;
    height: 22px;
  }
}

@keyframes qxs-icon-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

可用图标

查看所有可用图标,请参考:

最佳实践

图标类型选择

  1. 性能优先:优先使用 Vue 组件图标和 UnoCSS 图标,获得最佳性能
  2. 丰富选择:使用 Iconify 图标获得海量图标资源
  3. 自定义需求:使用图片 URL 支持品牌标识和自定义图标
  4. 兼容性考虑:使用 SVG Sprite 和 CSS 类图标兼容旧项目

使用建议

  1. 智能识别:组件会自动识别图标类型,无需手动指定
  2. 错误处理:为图片图标设置 fallbackloading 属性
  3. 样式一致:在同一界面中保持图标尺寸和颜色的一致性
  4. 语义化使用:选择符合功能语义的图标名称
  5. 性能考虑:避免在列表中使用大量图片 URL 图标

代码示例

vue
<template>
  <!-- ✅ 推荐:使用 Vue 组件图标 -->
  <QxsIcon :icon="HomeComponent" />

  <!-- ✅ 推荐:使用 Iconify 图标 -->
  <QxsIcon icon="ep:home" />

  <!-- ✅ 推荐:图片图标带错误处理 -->
  <QxsIcon
    icon="https://example.com/logo.png"
    fallback="i-ep:picture"
    loading="i-ep:loading"
  />

  <!-- ❌ 不推荐:图片图标不带错误处理 -->
  <QxsIcon icon="https://example.com/logo.png" />
</template>

Released under the MIT License.