当前位置:   article > 正文

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

iconify append-icon

前言:

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

需求:

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

步骤:

        1.选用插件:unplugin-icons与unplugin-vue-components(如果你不需要封装通用组件,那么两个插件就够了,unplugin-auto-import/vite插件是涉及到公共组件时需要配置的)----通过插件实现图标的自动导入和Vue组件的按需导入,无需手动导入图标,直接在模板中使用图标名称即可。这种方式更加自动化和便捷,但需要配置相应的插件和解析器。

          相关配置(vite.config.js)

  1. import AutoImport from 'unplugin-auto-import/vite'
  2. // icon相关插件
  3. import Components from 'unplugin-vue-components/vite'
  4. import Icons from 'unplugin-icons/vite'
  5. // icon 自动引入解析器
  6. import IconsResolver from 'unplugin-icons/resolver'
  7. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  8. import { FileSystemIconLoader } from 'unplugin-icons/loaders'
  9. // https://vitejs.dev/config/
  10. export default defineConfig({
  11. plugins: [
  12. vue(),
  13. AutoImport({
  14. imports: ['vue'],
  15. resolvers: [ElementPlusResolver(),IconsResolver({
  16. componentPrefix: "icon",
  17. enabledCollections: ["datalink", "mdi"],
  18. })],
  19. }),
  20. Components({
  21. resolvers: [
  22. ElementPlusResolver(),
  23. IconsResolver({
  24. // 自动引入的Icon组件统一前缀,默认为icon,设置false为不需要前缀
  25. prefix: 'icon',
  26. // 标识自定义图标集
  27. customCollections: ['datalink'],
  28. })
  29. ],
  30. }),
  31. Icons({
  32. // 默认的比例为1
  33. scale:1,
  34. compiler: 'vue3',// 指定编译器
  35. autoInstall: true,// 自动安装
  36. // 配置自定义的图标(里面直接放svg就行了)
  37. customCollections: {
  38. datalink: FileSystemIconLoader('./src/components/icon-iconify/icon-svg')
  39. }
  40. }),
  41. ]
  42. })

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

  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插件的配置导致的),要实现下放的功能,需要3个插件才行。

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>

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

闽ICP备14008679号