首页 > 其他分享 >vue3+vite+element-plus按需加载动态图标icon优化方案

vue3+vite+element-plus按需加载动态图标icon优化方案

时间:2023-03-09 23:35:58浏览次数:39  
标签:vue svg element unplugin plus import vite icon

1、问题:

element-plus中icon跟element中的icon完全不同,使用也很多变化,最重要的一点就是按需动态加载了,主要用到unplugin-icons这个库

根据按需加载icon的使用方法,是无法满足动态加载的

<template>
        <IEpPlus />
</template>

因为比如侧边栏列表的icon等很多都需要动态加载,就会发现以下代码是无法按需加载icon的

<script setup >
let obj = reactive([{ icon: 'IEpPlus' }, { icon: 'IEpMinus' }, { icon: 'IEpHouse' }, { icon: 'IEpDelete' }])
</script>
<template>
        <div v-for="(item, i) in obj" :key="i">
            <component :is="item.icon" />
        </div>
</template>

2、思路:

加载动态图标主要靠vue的component组件,而component导入大致分为两种,一个是注册为组件,然后传入组件名称字符串,第二个则是直接传入组件或者是html

所以其实解决问题方式就可以分成两类去解决

3、处理

注册解决法:网上很多的方案都是注册为vue组件,然后再使用。这样做是可以解决问题,但是不是最优解,因为你会把没有用到的icon也注册进去

// main.ts
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

组件传入法:配合unplugin-auto-import和unplugin-vue-components使用,它们让你不用手写import,极其方便

//vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'
import Icons from 'unplugin-icons/vite'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import IconsResolver from 'unplugin-icons/resolver'
export default defineConfig({
  css: {
  },
  plugins: [
    vue(),
    AutoImport({
      imports: ['vue', 'vue-router'],
      resolvers: [
        IconsResolver({
          enabledCollections: ['my', 'ep'],
        }),
        ElementPlusResolver()
      ],
    }),
    Components({
      resolvers: [
        IconsResolver({
          enabledCollections: ['my', 'ep'],
        }),
        ElementPlusResolver()
      ],
    }),
    Icons({
      compiler: "vue3",
      autoInstall: true,
      customCollections: {
        'my': FileSystemIconLoader('./src/assets/svg', svg => {
          svg = svg.replace(/fill="[A-Za-z0-9#(),]*"/g, '')
          svg = svg.replace(/width="[A-Za-z0-9]*"/g, '')
          svg = svg.replace(/height="[A-Za-z0-9]*"/g, '')
          svg = svg.replace(/^<svg /, '<svg fill="currentColor" ')
          return svg
        })
      }
    })
  ],
  resolve: {
    alias: {
      "~@": __dirname,
      "@": path.resolve(__dirname, "./src")
    }
  },
})

然后在组件中使用,不再是字符串的方式,而是直接引用

<script setup >
let obj = reactive([{ icon: IEpPlus }, { icon: IEpMinus }, { icon: IEpHouse }, { icon: IEpDelete }])
</script>

<template>
        <div v-for="(item, i) in obj" :key="i">
            <component :is="item.icon" />
        </div>
</template>

在js中使用也一样,比如在路由中使用,要加个shallowRef,不然会报错,最后把这个导入component就行了

//router.js
const routes = [
...
    {
    ...
        meta: {
            icon:shallowRef(IEpPlus)
}
    ...
     }
...
]

 

标签:vue,svg,element,unplugin,plus,import,vite,icon
From: https://www.cnblogs.com/lovewhatIlove/p/17201904.html

相关文章