vue-優雅的使用svg


背景

日前,開發一個配置數據表單類的框架,需要考慮框架的擴展性,以及使用的便捷性,其中圖標類如何便捷的引入也在考慮之中。

期望實現的效果是在新增一個svg時,僅將svg文件存放到某一個文件夾下,之后使用時通過類似於<mis-icon icon="name">這種方式即可使用。

思路

  1. 全局注冊組件
  2. 使用js讀取文件夾下的所有svg導入至項目中

實現

全局注冊組件

src/compoments下創建MisIcon.vue

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"/>
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    icon: {
      type: String,
      required: true,
    },
    className: {
      type: String,
      default: '',
    },
  },
  computed: {
    iconName () {
      return `#icon-${this.icon}`
    },
    svgClass () {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
  },
}
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

集中存放svg文件

  1. src/assets/svg文件夾下存放所有svg文件

    注意:如果需要修改svg的顏色,svg文件中的填充色 fill 必須刪除

  2. src/assets 下創建svg.js文件

    // 讀取所有svg文件
    const requireAll = requireContext => requireContext.keys().map(requireContext)
    const req = require.context('/src/assets/svg', false, /\.svg$/)
    requireAll(req)
    

全局注冊組件並導入svg

// main.js
import '@/assets/svg.js'
import MisIcon from '@/components/MisIcon.vue' // svg組件

// 注冊全局插件
Vue.component('mis-icon', MisIcon)

重要的一步 - 配置loader

根目錄下的vue.config.js文件中

const path = require('path')

function resolve(dir) {
  return path.join(__dirname, './', dir)
}

module.exports = {
  chainWebpack: config => {
    // svg 規則
    const svgRule = config.module.rule('svg') // 找到原有的svg-loader
    svgRule.uses.clear() // 清除已有的loader, 如果不清除會在原有loader之后再使用當前loader規則
    svgRule.exclude.add(/node_modules/) // 正則匹配排除node_modules目錄
    svgRule // 添加svg新的loader處理
      .test(/\.svg$/)
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      })

    // 修改images loader,添加svg處理
    const imagesRule = config.module.rule('images')
    imagesRule.exclude.add(resolve('src/assets/svg'))
    config.module
      .rule('images')
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
  }
}

使用

<template>
  <div>
    <!-- icon的值為svg文件名 -->
    <mis-icon icon="test" className="test-icon"></mis-icon>
  </div>
</template>

<script>
export default {
  name: 'SvgTest'
}
</script>

<style scoped>
  .test-icon{
    color: blue;
    width: 200px;
    height: 200px;
    &:hover{
      color: lightblue;
    }
  }
</style>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM