vue3 - 按需導(dǎo)入使用Element Plus圖標(biāo)、iconify圖標(biāo)、本地SVG/PNG圖標(biāo)

GitHub Demo 地址

在線預(yù)覽

vue項(xiàng)目使用的圖標(biāo)一般有本地的png、svg圖標(biāo),Element圖標(biāo),還有就是通過自動(dòng)導(dǎo)入使用三方庫(kù)iconify的圖標(biāo)

一、iconify插件

Iconify for Vue 官方文檔

Iconify內(nèi)的 element-plus圖標(biāo)

Iconify 是一個(gè)開源的圖標(biāo)集和圖標(biāo)管理工具。它提供了一個(gè)龐大的圖標(biāo)庫(kù),包含數(shù)千個(gè)常用圖標(biāo),涵蓋了各種主題和風(fēng)格,如 Material Design、Font Awesome、Feather 等。這些圖標(biāo)可以以矢量格式(SVG)使用,適用于各種項(xiàng)目,如網(wǎng)站、移動(dòng)應(yīng)用、桌面應(yīng)用等。

安裝

npm install --save-dev @iconify/vue

使用

用法

import { Icon } from '@iconify/vue'

    <!-- https://github.com/iconify/iconify/tree/main/components/vue -->
    <Icon icon="ep:add-location" height="24" />
    <Icon icon="mdi-light:home" width="16" height="16" />
    <Icon icon="mdi-light:home" height="24" />
    <Icon icon="mdi-light:home" height="2em" />
    <Icon icon="mdi-light:home" height="auto" />
    <Icon icon="eva:alert-triangle-fill" color="orange" />
    <Icon icon="eva:alert-triangle-fill" color="#f00" />

    <div>
      <!-- 水平翻轉(zhuǎn)圖標(biāo): -->
      <Icon icon="eva:alert-triangle-fill" :h-flip="true" />
      <Icon icon="eva:alert-triangle-fill" :horizontal-flip="true" />
      <Icon icon="eva:alert-triangle-fill" flip="horizontal" />
      <!-- 垂直翻轉(zhuǎn)圖標(biāo) -->
      <Icon icon="eva:alert-triangle-fill" :v-flip="true" />
      <Icon icon="eva:alert-triangle-fill" :vertical-flip="true" />
      <Icon icon="eva:alert-triangle-fill" flip="vertical" />
      <!-- 水平和垂直翻轉(zhuǎn)圖標(biāo)(與180度旋轉(zhuǎn)相同): -->
      <Icon icon="eva:alert-triangle-fill" :h-flip="true" :v-flip="true" />
      <Icon icon="eva:alert-triangle-fill" :horizontal-flip="true" :vertical-flip="true" />
      <Icon icon="eva:alert-triangle-fill" flip="horizontal,vertical" />
      <!-- 90度旋轉(zhuǎn)的例子: -->
      <Icon icon="eva:alert-triangle-fill" :rotate="1" />
      <!-- <Icon icon="eva:alert-triangle-fill" rotate="90deg" />
      <Icon icon="eva:alert-triangle-fill" rotate="25%" /> -->
    </div>

效果圖

二、通過自動(dòng)導(dǎo)入使用iconify

安裝Element Plus

element plus 按需導(dǎo)入 官方文檔
element plus 使用icon圖標(biāo) 官方文檔

通過element plus使用icon圖標(biāo),可以通過以下兩種方式(本文通過方式2)
1、可以通過命令npm install @element-plus/icons-vue單獨(dú)安裝icons-vue組件,然后使用
2、也可以通過使用 unplugin-iconsunplugin-auto-importiconify 中自動(dòng)導(dǎo)入任何圖標(biāo)集。 您可以參考此模板。

element plus使用icon圖標(biāo)一般是通過組件的方式使用的,如 <Search />,或者自動(dòng)導(dǎo)入配置后<i-ep-edit />

npm install element-plus

安裝自動(dòng)導(dǎo)入插件

安裝兩個(gè)按需導(dǎo)入的插件,避免在多個(gè)頁(yè)面重復(fù)引入 API 或 組件
unplugin-auto-import 按需自動(dòng)導(dǎo)入API,如:ref,reactive,watch,computed 等API
unplugin-vue-components 按需自動(dòng)導(dǎo)入組件,如:Element Plus 等三方庫(kù)和指定目錄下的自定義組件

npm install -D unplugin-auto-import unplugin-vue-components

安裝自動(dòng)導(dǎo)入 Icon 插件

使用 unplugin-iconsunplugin-auto-import可以從 iconify 中自動(dòng)導(dǎo)入圖標(biāo)

npm i -D unplugin-icons

vite.config.ts 配置自動(dòng)導(dǎo)入,新建 /src/types目錄用于存放自動(dòng)導(dǎo)入函數(shù)auto-imports.d.ts和組件的TS類型聲明文件components.d.ts

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

plugins: [
     AutoImport({
      // 自動(dòng)導(dǎo)入 Vue 相關(guān)函數(shù),如:ref, reactive, toRef 等
      imports: ['vue', '@vueuse/core'],
      // imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
      eslintrc: {
        enabled: false, // 是否自動(dòng)生成 eslint 規(guī)則,建議生成之后設(shè)置 false,手動(dòng)維護(hù)
        filepath: './.eslintrc-auto-import.json', // 指定自動(dòng)導(dǎo)入函數(shù) eslint 規(guī)則的文件路徑
        globalsPropValue: true
      },
      resolvers: [
        // 自動(dòng)導(dǎo)入 Element Plus 相關(guān)函數(shù),如:ElMessage, ElMessageBox... (帶樣式)
        ElementPlusResolver(),
        IconsResolver({})
      ],
      vueTemplate: true,
      // 配置文件生成位置(false:關(guān)閉自動(dòng)生成)
      dts: false
      // dts: 'src/types/auto-imports.d.ts' // 指定自動(dòng)導(dǎo)入函數(shù)TS類型聲明文件路徑
    }),

    Components({
      resolvers: [
        // 自動(dòng)導(dǎo)入 Element Plus 組件
        ElementPlusResolver(),
        // 自動(dòng)導(dǎo)入圖標(biāo)組件
        IconsResolver({
          // @iconify-json/ep 是 Element Plus 的圖標(biāo)庫(kù)
          enabledCollections: ['ep']
        })
      ],
      // 指定自定義組件位置(默認(rèn):src/components)
      dirs: ['src/**/components'],
      // 配置文件位置(false:關(guān)閉自動(dòng)生成)
      dts: false
      // dts: "src/types/components.d.ts",
    }),

    Icons({
      // 自動(dòng)安裝圖標(biāo)庫(kù)
      autoInstall: true
    }),
]

.eslintrc.cjs 添加自動(dòng)導(dǎo)入函數(shù) eslint 規(guī)則

"extends": [
    "./.eslintrc-auto-import.json"
]

tsconfig.json 添加自動(dòng)導(dǎo)入TS類型聲明文件

{
  "include": ["src/**/*.d.ts"]
}

運(yùn)行項(xiàng)目 npm run dev 查看效果

通過iconify使用Element Plus圖標(biāo)

<template>
    <h1>iconify 圖標(biāo):</h1>
    <div>
      <icon1 />
      <!-- <icon2 /> -->
      <icon3 />
    </div>
    
    <div>
      <i-ep-edit />
      <el-icon :size="19.2" color="#409eff">
        <i-ep-edit />
      </el-icon>
    </div>
</template>

<script setup lang="ts">
// element-plus圖標(biāo)
// https://icon-sets.iconify.design/ep/
import icon1 from '~icons/ep/help-filled'
// import { HelpFilled } from '@element-plus/icons-vue'

// 其他的
// https://icon-sets.iconify.design/
// import icon2 from '~icons/mdi/home-clock'
// 動(dòng)態(tài)圖標(biāo)
// https://icon-sets.iconify.design/line-md/
// https://icon-sets.iconify.design/svg-spinners/
import icon3 from '~icons/line-md/home'
</script>

效果圖

通過 UnoCSS,Element Plus 像 Element UI 一樣使用 Icon

Vue3!Element Plus 如何像 Element UI 一樣使用 Icon?

UnoCSS官網(wǎng)

UnoCSS 是一個(gè)具有高性能且極具靈活性的即時(shí)原子化 CSS 引擎 ,用于構(gòu)建響應(yīng)式網(wǎng)頁(yè)和應(yīng)用程序界面。它提供了一套簡(jiǎn)潔、易于使用的樣式類,幫助開發(fā)者快速搭建漂亮且功能強(qiáng)大的界面。

npm add -D unocss

vite.config.ts 配置

import UnoCSS from 'unocss/vite'
import { presetIcons } from 'unocss'

export default {
  plugins: [
  
    // 配置UnoCSS,使其可以直接使用標(biāo)簽 <i-ep-edit /> | <el-button icon="i-ep-edit" > edit </el-button>
    // UnoCSS({})
    UnoCSS({
      presets: [
        presetIcons({
          scale: 1.2,
          warn: true
        })
      ],
      // 以下配置是為了可以直接使用標(biāo)簽 <i-ep-edit /> | <el-button icon="i-ep-edit" > edit </el-button>
      variants: [
        {
          match: (s) => {
            if (s.startsWith('i-')) {
              return {
                matcher: s,
                selector: (s) => {
                  return s.startsWith('.') ? `${s.slice(1)},${s}` : s
                }
              }
            }
          }
        }
      ]
    })


  ],
}

main.ts 引入 uno.css

import 'uno.css'

示例

    <h2>el-button+圖標(biāo):</h2>
    <el-button type="primary">
      <el-icon> <i-ep-edit /> </el-icon> 新增
    </el-button>
    <el-button type="primary" icon="i-ep-edit"> 新增 </el-button>

效果圖

三、SVG本地圖標(biāo)

通過 vite-plugin-svg-icons 插件使用 Iconfont 第三方圖標(biāo)庫(kù)實(shí)現(xiàn)本地SVG圖標(biāo)展示
vite-plugin-svg-icons 官方文檔

npm install -D fast-glob
npm install -D vite-plugin-svg-icons

先指定一個(gè)存放svg的路徑,如:src/assets/iconssrc/assets/error

vite.config.ts 中配置插件

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'

const resolve = (dir: string) => path.resolve(process.cwd(), dir)

plugins: [
    createSvgIconsPlugin({
      // 指定需要緩存的圖標(biāo)文件夾
      iconDirs: [resolve('src/assets/icons'), resolve('src/assets/error')],
      // iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
      // 指定symbolId格式
      symbolId: 'icon-[dir]-[name]'
    }),
]

src/main.ts 內(nèi)引入注冊(cè)腳本

import 'virtual:svg-icons-register'

封裝一個(gè)SVG 組件以供項(xiàng)目使用
在src/components/創(chuàng)建SvgIcon文件夾,創(chuàng)建index.vue

<template>
  <svg aria-hidden="true" class="svg-icon" :style="'width:' + size + ';height:' + size">
    <use :xlink:href="symbolId" :fill="color" />
  </svg>
</template>

<script setup lang="ts">
const props = defineProps({
  prefix: {
    type: String,
    default: 'icon'
  },
  iconClass: {
    type: String,
    required: false,
    default: ''
  },
  color: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: '1em'
  }
})

const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`)
</script>

<style scoped>
.svg-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  overflow: hidden;
  vertical-align: -0.15em; /* 因icon大小被設(shè)置為和字體大小一致,而span等標(biāo)簽的下邊緣會(huì)和字體的基線對(duì)齊,故需設(shè)置一個(gè)往下的偏移比例,來(lái)糾正視覺上的未對(duì)齊效果 */
  outline: none;
  fill: currentcolor; /* 定義元素的顏色,currentColor是一個(gè)變量,這個(gè)變量的值就表示當(dāng)前元素的color值,如果當(dāng)前元素未設(shè)置color值,則從父元素繼承 */
}
</style>
<template>
     <h1>img SVG本地圖片:</h1>
    <svg-icon icon-class="homepage" />
    <svg-icon icon-class="user" color="red" />
</template>

<script setup lang="ts">
import SvgIcon from '@/components/SvgIcon/index.vue'
</script>

效果圖

四、本地PNG圖標(biāo)

vue3中使用本地圖標(biāo)和vue2還是有點(diǎn)區(qū)別

vue2使用的require,如:<img :src="require('@/assets/test.png')" />

vue3和vite中使用require會(huì)報(bào)錯(cuò)(require is not definedrequire is not defined),因?yàn)?code>require是webpack提供的方法,在vite中不適用。在vite中,由于使用了 ES modules 的方式來(lái)加載模塊,因此不能使用 require,而是使用import

以下是vue3中使用本地PNG圖標(biāo)的方式(調(diào)試和線上圖標(biāo)都顯示)

<template>
    <h1>img 本地PNG圖片:</h1>
    <img src="../../../assets/images/static/icon.png" />
    <img :src="imgPath2" />
    <img :src="imgPath3" />
    <img :src="imgPath4" />
    <img :src="imgPath5" />

    <h2>img 本地圖片動(dòng)態(tài)導(dǎo)入:</h2>
    <img :src="getImgPath2('icon2.png')" />
    <img :src="getImgPath3('icon3.png')" />
</template>

<script setup lang="ts">
import imgPath2 from '@/assets/images/static/icon2.png'
const imgPath3 = getImgPath('icon3.png')
const imgPath4 = new URL(`../../../assets/images/static/icon4.png`, import.meta.url).href
const imgPath5 = new URL(`@/assets/images/static/icon5.png`, import.meta.url).href

const getImgPath2 = (name: string): any => {
  return new URL(`/src/assets/images/static/${name}`, import.meta.url).href
}

const getImgPath3 = (name: string): any => {
  return new URL(`../../../assets/images/static/${name}`, import.meta.url).href
}

</script>

!!!!注意:

  TODO: 下面這樣寫加載失敗,也不可以用@/assets/xxx
  return new URL('/src/assets/images/static/' + name, import.meta.url).href

效果圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容