• 优雅的在Vue3 Vite3中模仿element-plus的图标使用方式


    最终实现效果

    使用效果如下

    <el-button icon="el-icon-send" type="primary">
     新增
    el-button>
    
    • 1
    • 2
    • 3

    使用Vue对svg文件进行封装

    准备文件

    直接将svg代码写入vue文件

    about.vue

    <template>
        <svg class="icon" viewBox="0 0 1229 1024" xmlns="http://www.w3.org/2000/svg" width="240.039" height="200">
            <path d="M727.59 511.004C817.748 467.99 880.387 375.63 880.387 268.53 880.387 120.549 761.052.147 614.391.147S348.4 120.549 348.4 268.53c0 107.098 62.674 199.46 152.792 242.474-224.396 55.89-328.166 277.36-328.166 485.41 0 14.89 11.962 26.876 26.643 26.876 14.76 0 26.68-12.027 26.68-26.876 0-214.47 121.399-445.341 388.01-445.341 266.604 0 388.004 230.871 388.004 445.341 0 14.89 11.96 26.876 26.678 26.876 14.721 0 26.643-12.027 26.643-26.876.074-208.051-103.656-429.522-328.093-485.41M401.72 268.53c0-118.315 95.37-214.583 212.67-214.583 117.297 0 212.675 96.268 212.675 214.583 0 118.276-95.376 214.511-212.675 214.511-117.301 0-212.67-96.235-212.67-214.511"/>
            <path d="M289.591 493.675c12.114-1.162 21.894-10.48 23.806-22.626 1.877-12.147-4.674-24.098-15.868-28.931-5.364-2.321-130.794-58.097-120.828-189.135C188.124 103.764 349.2 85.703 356.177 84.966c14.607-1.428 25.34-14.541 23.924-29.32-1.38-14.812-14.225-25.601-29.058-24.25C277.56 38.475 135.42 93.01 123.5 248.847c-7.324 96.924 44.313 166.582 95.411 207.43-88.82 31.206-234.37 119.899-216.354 364.072 1.034 14.118 12.728 24.947 26.523 24.947.692 0 1.347 0 2.039-.077 14.68-1.121 25.719-14.041 24.607-28.854-21.62-293.563 223.52-321.686 233.865-322.69m815.579-244.827C1093.283 93.05 951.185 38.513 877.702 31.397c-14.76-1.318-27.679 9.477-29.06 24.213-1.415 14.773 9.355 27.928 24 29.356 6.86.655 167.9 17.87 179.358 167.978 10.01 131.04-115.456 186.853-120.708 189.098-11.23 4.797-17.787 16.667-15.952 28.812 1.803 12.146 11.615 21.581 23.73 22.781 10.43 1.009 255.568 29.125 233.95 322.655-1.111 14.813 9.926 27.726 24.608 28.848.69.083 1.345.083 2.033.083 13.8 0 25.494-10.792 26.527-24.947 18.052-244.097-127.497-332.79-216.354-363.997 51.1-40.923 102.77-110.505 95.336-207.43z"/>
        svg>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    利用自己封装的SvgIcon简化代码,保持svg文件的可读性

    send.vue

    <template>
      <svg-icon icon-class="send" />
    template>
    <script>
    export default {
      name: 'send'
    }
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在main.js中注入所有相关文件

    /**
     * 使用vue嵌套svg文件之后将其批量注册全局组件,支持在类似el-button的icon属性中直接书写el-icon-edit使用edit.svg图标文件。
     * @param app 当前程序上下文
     */
    export function importSvgVue(app) {
      const importFn = import.meta.glob('./svgs/*', { eager: true })
      console.log(importFn)
      // 批量注册全局组件
      Object.keys(importFn).forEach(key => {
        let icon = key.substring(key.lastIndexOf('/') + 1, key.lastIndexOf('.'))
        icon = icon.substring(0, 1).toUpperCase() + icon.substring(1)
        console.log(icon, importFn[key])
        // 导入组件
        const component = importFn[key].default
        console.log(component)
        // 注册组件
        app.component(`ElIcon${icon}`, component)
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在注入时批量对svg文件进行封装简化【推荐】

    import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from 'vue'
    
    /**
     * 将svg文件批量注册全局组件,支持在类似el-button的icon属性中直接书写el-icon-edit使用edit.svg图标文件。
     * @param app 当前程序上下文
     */
    export function importSvg(app) {
      const importFn = import.meta.glob('./svg/*', { as: 'raw' })
      console.log(importFn)
      const components_exports_temp = {}
      for (const icon in importFn) {
        const fileName = icon.substring(icon.lastIndexOf('/') + 1, icon.lastIndexOf('.'))
        const iconName = fileName.substring(0, 1).toUpperCase() + fileName.substring(1)
    
        components_exports_temp[iconName] = () => createSvgIconComponent(iconName, fileName)
      }
      const components_exports = {}
      __export(components_exports, components_exports_temp)
    
      for (const [key, component] of Object.entries(components_exports)) {
        console.log(key, component)
        app.component(`ElIcon${key}`, component)
      }
    }
    
    /**
     * 创建svgIcon组件
     * 参考自{@link @element-plus/icons-vue/dist/index.js}
     * @param iconName  图标名称:Send
     * @param fileName  文件名称:send
     * @return {ComponentOptionsBase<{}, any, any, any, any, any, any, any> & ThisType>>}
     */
    function createSvgIconComponent(iconName, fileName) {
      function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
        const svgAttr = {
          class: 'svg-icon'
        }; const useNode = _createElementVNode('use', {
          href: `#icon-${fileName}`
        }); const children = [
          useNode
        ]
        return (_openBlock(), _createElementBlock('svg', svgAttr, children))
      }
      const vue_type_script_lang_default = {
        name: iconName
      }
      return export_helper_default(vue_type_script_lang_default, [['render', _sfc_render], ['__file', `${iconName}.vue`]])
    }
    
    /**
     * 参考自{@link @element-plus/icons-vue/dist/global.js}
     * @type {(o: T, p: PropertyKey, attributes: (PropertyDescriptor & ThisType)) => T}
     * @private
     */
    const __export = (target, all) => {
      for (const name in all) {
        Object.defineProperty(target, name, { get: all[name], enumerable: !0 })
      }
    }
    
    /**
     * 参考自{@link @element-plus/icons-vue/dist/global.js}
     * @param sfc
     * @param props
     * @return {ComponentOptionsBase<{}, any, any, any, any, any, any, any> & ThisType>>}
     */
    const export_helper_default = (sfc, props) => {
      // unplugin-vue:/plugin-vue/export-helper
      const target = sfc.__vccOpts || sfc
      for (const [key, val] of props) {
        target[key] = val
      }
      return target
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
  • 相关阅读:
    21天算法打卡系列(4)
    Linux网卡流量测速脚本
    本机idea连接虚拟机中的Hbase
    Spring高手之路14——深入浅出:SPI机制在JDK与Spring Boot中的应用
    【洛谷 P5143】攀爬者 题解(结构体排序)
    el-popover 通过js手动控制弹出框显示、隐藏
    【Linux】VMware下载和安装
    JNI查漏补缺(3)JNI调用java层
    DAY33 1005. K次取反后最大化的数组和 + 134. 加油站 + 135. 分发糖果
    java运行jar包
  • 原文地址:https://blog.csdn.net/qq_29185141/article/details/127806675