当前位置:   article > 正文

icon解决方案(iconify),基于unplugin-icons封装通用icon组件

unplugin-icons

前言:

        对于icon,前端的第一反应就是采用iconfont来做,对于多数场景当然是没有问题的,甚至后续项目中出现自定义icon只需要ui将设计传到iconfont平台就行了,但是毕竟还是经过了第三方平台的,所以我采用了iconify方案

需求:

        我现在的项目之前是用的MDI的图标库,后续因为ui陆续将icon设计出来了,所以也需要上传我们自己的自定义图标,所以需要兼容两种情况

步骤:

        1.选用插件:unplugin-icons与unplugin-auto-import/vite插件----通过插件实现图标的自动导入和Vue组件的按需导入,无需手动导入图标,直接在模板中使用图标名称即可。这种方式更加自动化和便捷,但需要配置相应的插件和解析器。

          相关配置(vite.config.js)

  1. // icon相关插件
  2. import AutoImport from 'unplugin-auto-import/vite'
  3. import Icons from 'unplugin-icons/vite'
  4. // icon 自动引入解析器
  5. import IconsResolver from 'unplugin-icons/resolver'
  6. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  7. import { FileSystemIconLoader } from 'unplugin-icons/loaders'
  8. // https://vitejs.dev/config/
  9. export default defineConfig({
  10. plugins: [
  11. vue(),
  12. AutoImport({
  13. imports: ['vue'],
  14. resolvers: [ElementPlusResolver(),IconsResolver({
  15. componentPrefix: "icon",
  16. enabledCollections: ["datalink", "mdi"],
  17. })],
  18. }),
  19. Icons({
  20. // 默认的比例为1
  21. scale:1,
  22. compiler: 'vue3',// 指定编译器
  23. autoInstall: true,// 自动安装(如果你用了element的icon但你没有下载对应的.json文件,它会自动帮你下载,如果你没这个需求,就不用设置)
  24. // 配置自定义的图标(里面直接放svg就行了)
  25. customCollections: {
  26. datalink: FileSystemIconLoader('./src/components/icon-iconify/icon-svg')
  27. }
  28. }),
  29. ]
  30. })

配置完成后,就可以在项目中直接使用了,插件可以自动的按需加载图标,不需要手动导入

  1. <template>
  2. <h1>
  3. icon方案测试1
  4. </h1>
  5. <!--使用其他的icon图标集,这里展示的element puls的(需要配置)-->
  6. <IconEpCellphone></IconEpCellphone>
  7. <!--使用自定义的svg图-->
  8. <IconDatalinkE/>
  9. <icon-mdi-bowl></icon-mdi-bowl>
  10. </template>

问题:

        但是接下来就引出一个新的问题了,如果我使用不同的图标库,这个使用图标组件的名称都有所区别比如说MDI:就是icon-mdi-xxxx,element puls: 就是icon-ep-xxxx 更别说我们的自定义图标了,所以为了统一,最好封装一个组件,这样我们使用时就比较统一了(接下来也就是本篇文章的重点)

        在github上,如果你去留意多数人提的问题,会发现,很多人都在询问能否通过动态的方法去生成icon图标呢,作者的统一回答都是 NO,原因是:

        由于unplugin-vue-components的工作机制,无法从动态字符串推断组件。 (unplugin-icons仅在构建时解析图标),如果你在运行后尝试动态生成,那是没有作用的

 相关问题:

Unable to use <Component :is="" · Issue #260 · unplugin/unplugin-icons · GitHub

  1. <!-- 通过is切换是不行的 -->
  2. <template #title>
  3. <el-icon v-if="menu.meta.icon"><component :is="menu.meta.icon"/></el-icon>
  4. <span>{{ menu.meta.title }}</span>
  5. </template>
  6. <menu-item v-for="(item, key) in menu.children" :key="key" :menu="item" :basePath="pathResolve" />
  7. </el-sub-menu>

   

解决:

        github上也有人提出对应的解决方案(提前将要使用的icon准备好就行了),这样就是在构建时完成了(如果还是不行,大概率是缺少unplugin-auto-import/vite插件的配置导致的),要实现下方的功能

https://github.com/unplugin/unplugin-icons/issues/5

  1. <template>
  2. <div class="p-icon" :class="[iconColor]">
  3. <component :is="icon" :width="iconSize" :height="iconSize"></component>
  4. </div>
  5. </template>
  6. <style lang="less">
  7. .p-icon {
  8. svg {
  9. fill: red;
  10. }
  11. &.p-icon-primary {
  12. svg {
  13. fill: red;
  14. }
  15. }
  16. }
  17. </style>
  18. <script setup>
  19. import { computed } from 'vue';
  20. const props = defineProps({
  21. icon: {
  22. type: String,
  23. default: '',
  24. },
  25. size: {
  26. type: [Number, String],
  27. default: 20,
  28. },
  29. primary: {
  30. type: Boolean,
  31. default: false,
  32. },
  33. });
  34. // 自定义图标集(:的右边部分就是插件的使用,根据你的配置名称可能会有所不同需要注意)
  35. const items = {
  36. 'jellyfish': IconDatalinkJellyfish,
  37. 'arrow-down': IconDatalinkArrowDown,
  38. 'arrow-left': IconDatalinkArrowLeft,
  39. 'arrow-right': IconDatalinkArrowRight,
  40. };
  41. const icon = computed(() => {
  42. const iconName = props.icon.split('icon-')[1];
  43. if (items[iconName]) {
  44. return items[iconName];
  45. }
  46. // 当图标不存在时,默认展示
  47. return items['jellyfish'];
  48. });
  49. const iconSize = computed(() => {
  50. return props.size;
  51. });
  52. const iconColor = computed(() => {
  53. if (props.primary) {
  54. console.log('是primary');
  55. return 'p-icon-primary';
  56. }
  57. return '';
  58. });
  59. </script>

小知识点:

        如果你试图改变svg的颜色,你发现改变不了,你可以去仔细看看,你的svg文件,内部是否存在一个默认fill属性,你需要将其删除,通过css给svg上颜色就行了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/770991
推荐阅读
相关标签
  

闽ICP备14008679号