Detailed graphic explanation of how to use svg in vue3+vite project

Detailed graphic explanation of how to use svg in vue3+vite project

Today, in the practice of vue3+vite project, when using svg, I found that the previous writing method could not be used. The previous usage method refers to the elegant use of svg in vue2

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

Then I searched for various materials and finally realized it. Without further ado, here is the code:

stept1: File directory

stept2: Install svg-sprite-loader

npm install svg-sprite-loader -D
# via yarn
yarn add svg-sprite-loader -D

Step 3: Create svgIcon.vue file

   <template>
  <svg :class="svgClass" v-bind="$attrs" :style="{color: color}">
    <use :xlink:href="iconName" rel="external nofollow" />
  </svg>
</template>

<script setup>


import { defineProps, computed } from "vue";

const props = defineProps({
  name: {
      type: String,
      required: true
    },
    color:
      type: String,
      default: ''
    }
})

const iconName = computed(()=>`#icon-${props.name}`);
const svgClass = computed(()=> {
  console.log(props.name, 'props.name');
  if (props.name) {
        return `svg-icon icon-${props.name}`
      }
      return 'svg-icon'
});
</script>

<style lang='scss'>
.svg-icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  vertical-align: middle;
}
</style>

stept4: Create an icons folder to store svg files

stept5: Inject svg-icon component globally in main.js

import { createApp } from 'vue'
import App from './App.vue'

import svgIcon from './components/svgIcon.vue'

createApp(App).component('svg-icon', svgIcon).mount('#app');

stept6: Create svgBuilder.js in the plugins folder (here comes the key point), ts version reference: https://github.com/JetBrains/svg-sprite-loader/issues/434

import { readFileSync, readdirSync } from 'fs'

let idPerfix = ''
const svgTitle = /<svg([^>+].*?)>/
const clearHeightWidth = /(width|height)="([^>+].*?)"/g

const hasViewBox = /(viewBox="[^>+].*?")/g

const clearReturn = /(\r)|(\n)/g

function findSvgFile(dir) {
  const svgRes = []
  const dirents = readdirSync(dir, {
    withFileTypes: true
  })
  for (const dirent of dirents) {
    if (dirent.isDirectory()) {
      svgRes.push(...findSvgFile(dir + dirent.name + '/'))
    } else {
      const svg = readFileSync(dir + dirent.name)
        .toString()
        .replace(clearReturn, '')
        .replace(svgTitle, ($1, $2) => {
          // console.log(++i)
          // console.log(dirent.name)
          let width = 0
          let height = 0
          let content = $2.replace(
            clearHeightWidth,
            (s1, s2, s3) => {
              if (s2 === 'width') {
                width = s3
              } else if (s2 === 'height') {
                height = s3
              }
              return ''
            }
          )
          if (!hasViewBox.test($2)) {
            content += `viewBox="0 0 ${width} ${height}"`
          }
          return `<symbol id="${idPerfix}-${dirent.name.replace(
            '.svg',
            ''
          )}" ${content}>`
        })
        .replace('</svg>', '</symbol>')
      svgRes.push(svg)
    }
  }
  return svgRes
}

export const svgBuilder = (path, perfix = 'icon') => {
  if (path === '') return
  idPerfix = perfix
  const res = findSvgFile(path)
  // console.log(res.length)
  // const res = []
  return {
    name: 'svg-transform',
    transformIndexHtml(html) {
      return html.replace(
        '<body>',
        `
          <body>
            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
              ${res.join('')}
            </svg>
        `
      )
    }
  }
}

stept7: Finally, modify the configuration in vite.config.js

import { svgBuilder } from './src/plugins/svgBuilder'; 

export default defineConfig({
  plugins: [svgBuilder('./src/icons/svg/')] // All svg files under src/icons/svg/ have been imported here, no need to import them separately})

Summarize

This is the end of this article on how to use SVG in Vue3+Vite projects. For more relevant content about using SVG in Vue3+Vite, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of vite2.0+vue3 mobile project

<<:  CSS pixels and solutions to different mobile screen adaptation issues

>>:  How to use shell to perform batch operations on multiple servers

Recommend

Provides helpful suggestions for improving website design

<br />Scientifically Design Your Website: 23...

Docker link realizes container interconnection

Table of contents 1.1. Network access between con...

Summary of Common Mistakes in Web Design

In the process of designing a web page, designers...

Implementation of Docker container connection and communication

Port mapping is not the only way to connect Docke...

How to use vw+rem for mobile layout

Are you still using rem flexible layout? Does it ...

Docker configuration Alibaba Cloud Container Service operation

Configuring Alibaba Cloud Docker Container Servic...

How to generate a unique server-id in MySQL

Preface We all know that MySQL uses server-id to ...

Detailed explanation of the execution order of JavaScript Alert function

Table of contents question analyze solve Replace ...

Summary of 4 solutions for returning values ​​on WeChat Mini Program pages

Table of contents Usage scenarios Solution 1. Use...

Detailed explanation on how to modify the default port of nginx

First find out where the configuration file is wh...

dl, dt, dd list label examples

The dd and dt tags are used for lists. We usually...

Detailed explanation of JavaScript closure issues

Closures are one of the traditional features of p...