1. Install dependencies

npm install svg-sprite-loader --save-dev
Copy the code

2. Set the parameters in vue.config.js

const path = require('path') const webpack = require('webpack') module.exports = { chainWebpack: Rule (' SVG ').exclude. Add (path.resolve(' SRC/ICONS ')).end(); Config.module. rule('svg-sprite-loader').test(/\.svg$/).include.add (path.resolve('./ SRC/ICONS ')) .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) }, }Copy the code

3. Create the svgIcon component in Components

<template> <i :class="['svg-icon', `svg-icon-${iconClass}`, className]" :style="svgStyle"> <svg fill="currentColor" aria-hidden="true" width="1em" height="1em"> <use :xlink:href="iconName" /> </svg> </i> </template> <script> export default { name: "SvgIcon", props: { iconClass: { type: String, required: true }, className: { type: String }, color: { type: String }, size: { type: Number } }, computed: { iconName() { return `#icon-${this.iconClass}`; }, svgClass() { if (this.className) { return `${this.className}`; } return ""; }, svgStyle() { const { color, size } = this; const style = {}; color && (style.color = color); size && (style.fontSize = `${size}px`); return style; }}}; </script> <style scoped>. Svg-icon {vertical-align: -0.12em; line-height: 0; display: inline-block; } </style>Copy the code

4. Place and render the image

Create an ICONS folder under SRC, create an SVG folder in the ICONS folder, and put the SVG images you want to use in this folder. In addition, create the index.js file in the ICONS folder

Import Vue from 'Vue' import SvgIcon from '@/components/SvgIcon' // Vue.com (' svG-icon ', SvgIcon) const requireAll = requireContext => requireContext.keys().map(requireContext) const req = Require.context ('./ SVG ', true, /\.svg$/)// This line of code will go to the SVG folder (excluding subdirectories) to find all files whose names end in.svg that can be required. // We introduce the corresponding file module through regular matching. // require.context has three parameters: // directory: specifies the directory that needs to be retrieved // useSubdirectories: specifies whether a subdirectory needs to be retrieved // regExp: specifies the regular expression requireAll(req) that matches the file.Copy the code

5. Globally introduce svgIcon in main.js

Import './ ICONS /index.js' // import SVGCopy the code

6. Use it in your project

<div> < svG-icon iconClass="svgName" :size="60" color="orange" /> </div>Copy the code

Note:

SVG will inherit the color value of the parent element, but only if the path or g attributes cannot have fill and fill-rule attributes. This will disable currentColor and simply remove the fill attribute manually

So, setting color is ok

7. Project icon preview

The next problem to solve is the local icon preview, continue to use the webpack-require-context method, get the local icon name, and then load it

<script> // Get all SVG names const ICONS = require. context("@/ ICONS/SVG ", false, /\.svg$/) .keys() .map(name => name.replace(/^\.\/([\w-]+)\.svg/, "$1")); export default { name: 'SvgViewer', methods: { async handleIconClick(iconName) { await navigator.clipboard.writeText(`<svg-icon iconClass='${iconName}' />`); // alert(' ${iconName} icon code copied to clipboard '); } }, render() { const { SvgIcon } = this.$options.components; <p> {ICONS. Map (iconName => (<div class="icon" on-click={() =>) this.handleIconClick(iconName)}> <svg-icon iconClass={iconName} /> <span class="icon-name">{iconName}</span> </div> ))} </div> ); }, } </script> <style lang="less" scoped> .icon-view { padding: 10px; > p { margin-bottom: 20px; font-size: 20px; text-align: center; } .icon { display: inline-block; width: 50px; margin-right: 20px; margin-bottom: 30px; text-align: center; cursor: pointer; /deep/ svg { display: block; width: 40px; height: 40px; } .icon-name { display: block; width: 100%; .ellipsis1; } } } </style>Copy the code

Look at the results:

References:

Vuecli-svg-sprite-loader (vuecli-SVG-sprite-loader)

Elegant use of SVG diagrams in VUE projects