美文网首页vue
vue3 - 按需导入使用Element Plus图标、icon

vue3 - 按需导入使用Element Plus图标、icon

作者: 西半球_ | 来源:发表于2023-10-07 15:58 被阅读0次

    GitHub Demo 地址

    在线预览

    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-iconsunplugin-auto-importiconify 中自动导入任何图标集。 您可以参考此模板

    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-iconsunplugin-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/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({
          // 指定需要缓存的图标文件夹
          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),因为requirewebpack提供的方法,在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).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
    

    效果图

    相关文章

      网友评论

        本文标题:vue3 - 按需导入使用Element Plus图标、icon

        本文链接:https://www.haomeiwen.com/subject/gbhkbdtx.html