Using svg (component) in vue

Using svg in the vue project has the following steps:

1. Installation  svg-sprite-loader dependencies

npm install svg-sprite-loader --save-dev

2.  Create a src new directory under the directory  to store all the icon  files src/icons/svg used in the project svg

     Add configuration in  vue-config.js :

module.exports = {
  chainWebpack(config) {
     //配置svg
      config.module
        .rule('svg')
        .exclude.add(resolve('src/icons'))
        .end()
      config.module
        .rule('icons')
        .test(/\.svg$/)
        .include.add(resolve('src/icons'))
        .end()
        .use('svg-sprite-loader')
        .loader('svg-sprite-loader')
        .options({
          symbolId: 'icon-[name]'
        })
        .end()
  },

3. Create components components/SvgIcon.vue

<template>
  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" ></div>
  <svg v-else :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script>
import { isExternal } from '@/utils/validate'
import '@/icons'

export default {
  name: 'svg-icon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    isExternal() {
      return isExternal(this.iconClass)
    },
    iconName() {
      return `#icon-${this.iconClass}`
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
    styleExternalIcon() {
      return {
        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
      }
    }
  }
}
</script>

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

.svg-external-icon {
  background-color: currentColor;
  mask-size: cover!important;
  display: inline-block;
}
</style>

isExternal file and its function

/**校验传入的iconClass是否为外部链接
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

4.  src/icons Create  icons a file in the directory

 index.js

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component

// register globally
Vue.component('svg-icon', SvgIcon)

const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)

If there are many project icon files, you can  icons divide the directory in detail, and then modify the above index.js

main.js Introduced globally in the entry  file  icons.

// main.js
import "./icons";

5. Use svg components

 <svg-icon icon-class="svgName" class="icon" />
//svgName为.svg后缀前的文件名

// 引入组件
import SvgIcon from '@/components/SvgIcon'
components: {
    SvgIcon
}

Note: The style in svg is  fillcontrolled by attributes, and it cannot be modified if it is written in the inline style; if the inline style is given a color, then the child element needs to explicitly specify that it  fillinherits from the parent element (otherwise the weight of inheritance is very low, and the style cannot be applied)

svg path {
    fill:inherit
}

Guess you like

Origin blog.csdn.net/m0_65835778/article/details/128235580