在vue3+vite項(xiàng)目中使用svg

今天在vue3+vite項(xiàng)目練習(xí)中,在使用svg時(shí)押逼,發(fā)現(xiàn)之前的寫(xiě)法不能用,之前的使用方法參考:vue2中優(yōu)雅的使用svg

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

然后就各種資料查找学搜,終于實(shí)現(xiàn)了位谋,廢話(huà)不多說(shuō),直接上代碼:

stept1: 文件目錄

image

stept2: 安裝 svg-sprite-loader

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

stept3: 創(chuàng)建svgIcon.vue文件

   <template>
  <svg :class="svgClass" v-bind="$attrs" :style="{color: color}">
    <use :xlink:href="iconName"/>
  </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: 創(chuàng)建icons文件夾遥椿,存放svg文件

stept5: 在main.js里面全局注入svg-icon組件

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

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

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

stept6: 在plugins文件夾創(chuàng)建svgBuilder.js(重點(diǎn)來(lái)了), ts版本參考: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: 最后在vite.config.js修改配置

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

export default defineConfig({
  plugins: [svgBuilder('./src/icons/svg/')] // 這里已經(jīng)將src/icons/svg/下的svg全部導(dǎo)入基矮,無(wú)需再單獨(dú)導(dǎo)入
})

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冠场,隨后出現(xiàn)的幾起案子家浇,更是在濱河造成了極大的恐慌,老刑警劉巖碴裙,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钢悲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡青团,警方通過(guò)查閱死者的電腦和手機(jī)譬巫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)督笆,“玉大人芦昔,你說(shuō)我怎么就攤上這事⊥拗祝” “怎么了咕缎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)料扰。 經(jīng)常有香客問(wèn)我凭豪,道長(zhǎng),這世上最難降的妖魔是什么晒杈? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任嫂伞,我火速辦了婚禮,結(jié)果婚禮上拯钻,老公的妹妹穿的比我還像新娘帖努。我一直安慰自己,他們只是感情好粪般,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拼余。 她就那樣靜靜地躺著,像睡著了一般亩歹。 火紅的嫁衣襯著肌膚如雪匙监。 梳的紋絲不亂的頭發(fā)上凡橱,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音亭姥,去河邊找鬼稼钩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛达罗,可吹牛的內(nèi)容都是我干的变抽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼氮块,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绍载!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起滔蝉,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤击儡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蝠引,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體阳谍,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年螃概,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了矫夯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吊洼,死狀恐怖训貌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冒窍,我是刑警寧澤递沪,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站综液,受9級(jí)特大地震影響款慨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谬莹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一檩奠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧附帽,春花似錦埠戳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)送悔。三九已至慢显,卻和暖如春爪模,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荚藻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工屋灌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人应狱。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓共郭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親疾呻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子除嘹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容