美文网首页
svg组件封装

svg组件封装

作者: bypwan | 来源:发表于2021-04-22 16:54 被阅读0次

    svg图片的优点

    1,任意放缩。 用户可以任意缩放图像显示,而不会破坏图像的清晰度、细节等。
    2,文本独立。 SVG图像中的文字独立于图像,文字保留可编辑和可搜寻的状态。
    3,较小文件。 总体来讲,SVG文件比那些GIF和JPEG格式的文件要小很多,因而下载也很快。
    4,超级颜色控制
    5,。。。。。
    基于以上优点,项目中使用svg图片
    由于用的地方比较多,考虑封装全局svg-icon组件,然后通过vue.component()挂载到全局

    文件目录说明:icons文件夹下包含svg文件夹,放的是svg图片,和svg文件夹同级别的是index.js文件(注册全局组件,批量引入svg图片文件)
    svg组件封装
    SvgIcon/index.vue

    <template>
      <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
      <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
        <use :xlink:href="svgName" />
      </svg>
    </template>
    <script>
      import { isExternal } from '@/library/utils/validate'
      export default {
        name: 'SvgIcon',
        props: {
          iconName: {
            type: String,
            required: true
          },
          className: {
            type: String,
            default: ''
          }
        },
        computed: {
          isExternal () {
            return isExternal(this.iconName)
          },
          svgName () {
            return `#icon-${this.iconName}`
          },
          svgClass () {
            if (this.className) {
              return 'svg-icon ' + this.className
            } else {
              return 'svg-icon'
            }
          },
          styleExternalIcon () {
            return {
              mask: `url(${this.iconName}) no-repeat 50% 50%`,
              '-webkit-mask': `url(${this.iconName}) no-repeat 50% 50%`
            }
          }
        }
      }
    </script>
    <style scoped>
      .svg-icon {
        width: 1em;
        height: 1em;
        vertical-align: -0.15em;
        fill: currentColor;
        overflow: hidden;
      }
    
      .svg-external-icon {
        background-color: currentColor;
        mask-size: cover !important;
        display: inline-block;
      }
    </style>
    

    将上面的组件注册为全局组件,批量引入文件
    icons/index.js

    import Vue from 'vue'
    import SvgIcon from '@/components/SvgIcon'
    
    Vue.component('svg-icon', SvgIcon)
    // 第一个参数为文件夹名称,第二个参数为是否检查其子目录,第三个参数为正则表达式
    const req = require.context('./svg', false, /\.svg$/)   
    // 返回结果为一个函数,该函数有3个属性,
      // a,resolve{Function} : 是一个函数,返回已分析请求的模块id
    //b,keys : 返回上下文模块可以处理的所有可能请求的数组的函数
    //c,id : 是上下文模块的模块id。这可能对module.hot.acce有用
    
    const requireAll = requireContext => requireContext.keys().map(requireContext)
    requireAll(req)
    

    对requireAll方法的解释:

    const requireAll = requireContext => requireContext.keys().map(requireContext)
    

    等同于

    function(requireContext) {
        requireContext.keys() // 得到了所有导入的模块名数组
                      .map(function(moduleName){
                                autorequire(moduleName) // webpack 自动导入 
                                })
                                    }
    
    

    require.context 是webpack的一个api,通过执行require.context()函数,来获取指定的文件夹内的特定文件,在需要多次从同一个文件夹内倒入的模块,使用这个函数可以自动倒入,不用每个都显示的写import来引入。(我们的例子就是需要多次从svg文件夹下多次导入文件)

    在main的入口文件引入

    // 导入 svg 图标
    import './icons
    

    使用

    <template>
      <div class="app-result app-result-403">
        <div class="app-result-icon app-result-image">
          <svg-icon icon-name="403-page" class-name="error-403" />
        </div>
        <div class="app-result-title">
          403
        </div>
        <div class="app-result-subtitle">
          抱歉,您无权访问此页面。
        </div>
        <div class="app-result-extra">
          <a href="/">
            <el-button type="primary">返回首页</el-button>
          </a>
        </div>
      </div>
    </template>
    <style scoped>
    .error-403 {
      width: 251px;
      height: 294px;
    }
    </style>
    

    相关文章

      网友评论

          本文标题:svg组件封装

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