图标组件

167 阅读1分钟

一.初步引入和使用

图标解决方案 Bootstrap、Fontawesome、Ionicons 选用Fontawesome

# 安装 svg core
npm i --save @fortawesome/fontawesome-svg-core
# 安装图标库
npm i --save @fortawesome/free-solid-svg-icons 
# 安装基于 vue3 的包装
npm i --save @fortawesome/vue-fontawesome@latest-3

在main.js中引入


import { createApp } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faUserSecret } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import App from './App.vue'
library.add(faUserSecret)
import './style/index.css'

createApp(App)
    .component('font-awesome-icon', FontAwesomeIcon)  //注册全局组件
    .mount('#app')

使用:

<font-awesome-icon icon="fa-solid fa-user-secret" />

二.二次开发

Icon组件

Icon.vue:

<template>
    <i class="lu-icon">
        <font-awesome-icon v-bind="$props"/>
    </i>
</template>

<script lang="ts" setup>
import { defineOptions } from 'vue';
import type {FontAwesomeIconProps} from '@fortawesome/vue-fontawesome'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
defineOptions({
    name: 'LuIcon',
    inheritAttrs:false
})
defineProps <FontAwesomeIconProps>()

</script>    

types.ts中引入类型

import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'

设置类型和颜色 :

<template>
    <i
      class="lu-icon"
      :class="{ [`lu-icon--${props.type}`]: props.type }"
      :style="{ color: props.color || undefined }"
    >
      <font-awesome-icon v-bind="iconProps" />
    </i>
  </template>
  
  <script lang="ts" setup>
  import { omit } from 'lodash-es';
  import type { IconProps } from './types';
  import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome';
  import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
  import { defineOptions } from 'vue';
  import { computed } from 'vue';
  defineOptions({
    name: 'LuIcon',
    inheritAttrs: false
  });
  
  type MergedProps = IconProps & FontAwesomeIconProps;
  const props = defineProps<MergedProps>();
  
  // 过滤掉内部用的属性,不传给 font-awesome-icon
  const iconProps = computed(()=>omit(props, ['type', 'color']));
  </script>
  
  <style>
  /* 通用样式 */
  .lu-icon {
    --lu-icon-color: inherit;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    position: relative;
    fill: currentColor;
    color: var(--lu-icon-color);
    font-size: inherit;
  }
  
  /* type 类型对应的颜色变量 */
  .lu-icon--primary {
    --lu-icon-color: var(--lu-color-primary);
  }
  
  .lu-icon--info {
    --lu-icon-color: var(--lu-color-info);
  }
  
  .lu-icon--success {
    --lu-icon-color: var(--lu-color-success);
  }
  
  .lu-icon--warning {
    --lu-icon-color: var(--lu-color-warning);
  }
  
  .lu-icon--danger {
    --lu-icon-color: var(--lu-color-danger);
  }
  </style>
  
import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'

export interface IconProps {
    type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
    color?: string
}

给按钮添加icon

<template>
    <button ref="_ref" class="lu-button" :class="{
        [`lu-button--${type}`]: type,
        [`lu-button--${size}`]: size,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle,
        'is-disabled': disabled,
        'is-loading':loading

    }" :disabled="disabled || loading" :autofocus="autofocus" :type="nativeType">
        <icon icon="spinner" spin v-if="loading"></icon>
        <icon :icon="icon" v-if="icon"></icon>
        <span>
            <slot></slot>
        </span>
    </button>
</template>

App.vue中使用:

<Button type="primary" size="large" loading>Loading</Button>
<Button type="primary" size="large" icon="arrow-up">Icon</Button>

实现效果:

image.png