GitHub Demo 地址
在线预览
vue3 - 按需导入使用Element Plus图标、iconify图标、本地SVG/PNG图标
- [GitHub Demo 地址](https://github.com/iotjin/jh-vue3-admin)
- [在线预览 ](https://iotjin.github.io/jh-vue3-admin)
- 一、iconify插件
- 安装
- 使用
- 效果图
- 二、通过自动导入使用iconify
- 安装Element Plus
- 安装自动导入插件
- 安装自动导入 Icon 插件
- 通过iconify使用Element Plus图标
- 效果图
- 通过 UnoCSS,Element Plus 像 Element UI 一样使用 Icon
- 效果图
- 三、SVG本地图标
- 效果图
- 四、本地PNG图标
- 效果图
vue项目使用的图标一般有
本地
的png、svg图标,Element
图标,还有就是通过自动导入
使用三方库iconify
的图标
一、iconify插件
Iconify for Vue 官方文档
Iconify内的 element-plus图标
Iconify 是一个开源的图标集和图标管理工具。它提供了一个庞大的图标库,包含数千个常用图标,涵盖了各种主题和风格,如 Material Design、Font Awesome、Feather 等。这些图标可以以矢量格式(SVG)使用,适用于各种项目,如网站、移动应用、桌面应用等。
安装
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><!-- 水平翻转图标: --><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" /><!-- 垂直翻转图标 --><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" /><!-- 水平和垂直翻转图标(与180度旋转相同): --><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度旋转的例子: --><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>
效果图
二、通过自动导入使用iconify
安装Element Plus
element plus 按需导入 官方文档
element plus 使用icon图标 官方文档
通过
element plus
使用icon图标,可以通过以下两种方式(本文通过方式2)
1、可以通过命令npm install @element-plus/icons-vue
单独安装icons-vue
组件,然后使用
2、也可以通过使用 unplugin-icons 和 unplugin-auto-import 从iconify
中自动导入任何图标集。 您可以参考此模板。
element plus
使用icon图标一般是通过组件的方式使用的,如<Search />
,或者自动导入配置后<i-ep-edit />
npm install element-plus
安装自动导入插件
安装两个按需导入的插件,避免在多个页面重复引入 API 或 组件
unplugin-auto-import
按需自动导入API,如:ref,reactive,watch,computed 等API
unplugin-vue-components
按需自动导入组件,如:Element Plus 等三方库和指定目录下的自定义组件
npm install -D unplugin-auto-import unplugin-vue-components
安装自动导入 Icon 插件
使用
unplugin-icons
和unplugin-auto-import
可以从iconify
中自动导入图标
npm i -D unplugin-icons
在
vite.config.ts
配置自动导入,新建/src/types
目录用于存放自动导入函数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({// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等imports: ['vue', '@vueuse/core'],// imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],eslintrc: {enabled: false, // 是否自动生成 eslint 规则,建议生成之后设置 false,手动维护filepath: './.eslintrc-auto-import.json', // 指定自动导入函数 eslint 规则的文件路径globalsPropValue: true},resolvers: [// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)ElementPlusResolver(),IconsResolver({})],vueTemplate: true,// 配置文件生成位置(false:关闭自动生成)dts: false// dts: 'src/types/auto-imports.d.ts' // 指定自动导入函数TS类型声明文件路径}),Components({resolvers: [// 自动导入 Element Plus 组件ElementPlusResolver(),// 自动导入图标组件IconsResolver({// @iconify-json/ep 是 Element Plus 的图标库enabledCollections: ['ep']})],// 指定自定义组件位置(默认:src/components)dirs: ['src/**/components'],// 配置文件位置(false:关闭自动生成)dts: false// dts: "src/types/components.d.ts",}),Icons({// 自动安装图标库autoInstall: true}),
]
在
.eslintrc.cjs
添加自动导入函数 eslint 规则
"extends": ["./.eslintrc-auto-import.json"
]
在
tsconfig.json
添加自动导入TS类型声明文件
{"include": ["src/**/*.d.ts"]
}
运行项目 npm run dev 查看效果
通过iconify使用Element Plus图标
<template><h1>iconify 图标:</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图标
// 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'
// 动态图标
// 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官网
UnoCSS 是一个具有高性能且极具灵活性的即时原子化 CSS 引擎 ,用于构建响应式网页和应用程序界面。它提供了一套简洁、易于使用的样式类,帮助开发者快速搭建漂亮且功能强大的界面。
npm add -D unocss
vite.config.ts
配置
import UnoCSS from 'unocss/vite'
import { presetIcons } from 'unocss'export default {plugins: [// 配置UnoCSS,使其可以直接使用标签 <i-ep-edit /> | <el-button icon="i-ep-edit" > edit </el-button>// UnoCSS({})UnoCSS({presets: [presetIcons({scale: 1.2,warn: true})],// 以下配置是为了可以直接使用标签 <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+图标:</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本地图标
通过
vite-plugin-svg-icons
插件使用Iconfont
第三方图标库实现本地SVG图标展示
vite-plugin-svg-icons 官方文档
npm install -D fast-glob
npm install -D vite-plugin-svg-icons
先指定一个存放svg的路径,如:src/assets/icons
和src/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({// 指定需要缓存的图标文件夹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
内引入注册脚本
import 'virtual:svg-icons-register'
封装一个SVG 组件以供项目使用
在src/components/创建SvgIcon
文件夹,创建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大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */outline: none;fill: currentcolor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置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图标
vue3中使用本地图标和vue2还是有点区别
vue2使用的
require
,如:<img :src="require('@/assets/test.png')" />
vue3和vite中使用
require
会报错(require is not definedrequire is not defined
),因为require
是webpack
提供的方法,在vite
中不适用。在vite中,由于使用了ES modules
的方式来加载模块,因此不能使用require
,而是使用import
以下是vue3中使用本地PNG图标的方式(调试和线上图标都显示)
<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 本地图片动态导入:</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).hrefconst 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>