Vue 프로젝트에서 사용자 정의 SVG 아이콘 컴포넌트 구현하기

프로젝트에서 vue-element-admin을 활용할 때, 학습 방법으로 직접 구성 요소를 만들어보는 방식을 선호합니다. 이러한 접근은 느릴 수 있지만 세부 사항까지 깊이 이해하는 데 도움이 됩니다. 이번 문서에서는 사용자 정의 SVG 아이콘 컴포넌트를 만드는 과정과 주요 단계를 기록하겠습니다.

먼저 svg-sprite-loader를 설치합니다.

yarn add svg-sprite-loader

다음으로, 전역적으로 사용할 수 있는 SVG 아이콘 컴포넌트를 설정합니다. components/SvgIcon/index.vue 파일을 생성하세요.

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

<script>
export default {
  name: "CustomSvgIcon",
  props: {
    icon: {
      type: String,
      required: true,
    },
    customClass: {
      type: String,
      default: "",
    },
  },
  computed: {
    symbolId() {
      return `#icon-${this.icon}`;
    },
    iconClass() {
      if (this.customClass) {
        return `svg-icon ${this.customClass}`;
      }
      return "svg-icon";
    },
  },
};
</script>

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

다음으로, src/icons 디렉토리를 생성하고 그 안에 index.jssvg 디렉토리를 추가합니다. SVG 파일들은 svg 디렉토리에 배치됩니다.

index.js 파일의 내용은 다음과 같습니다:

import Vue from "vue";
import SvgIcon from "@/components/SvgIcon";

// 전역 컴포넌트 등록
Vue.component("custom-svg-icon", SvgIcon);

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

SVG 로더를 구성하려면 vue.config.js에서 chainWebpack 메서드를 사용하여 설정합니다.

"use strict";
const path = require("path");

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

module.exports = {
  publicPath: "/",
  outputDir: "dist",
  assetsDir: "static",
  lintOnSave: process.env.NODE_ENV === "development",
  productionSourceMap: false,
  
  configureWebpack: {
    name: "G-test",
    resolve: {
      alias: {
        "@": resolve("src"),
      },
    },
  },
  chainWebpack(config) {
    config.plugins.delete("preload");
    config.plugins.delete("prefetch");

    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();

    config.module
      .rule("vue")
      .use("vue-loader")
      .loader("vue-loader")
      .tap((options) => {
        options.compilerOptions.preserveWhitespace = true;
        return options;
      });

    config.when(process.env.NODE_ENV === "development", (config) =>
      config.devtool("cheap-source-map")
    );

    config.when(process.env.NODE_ENV !== "development", (config) => {
      config.optimization.splitChunks({
        chunks: "all",
        cacheGroups: {
          libs: {
            name: "chunk-libs",
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: "initial",
          },
          elementUI: {
            name: "chunk-elementUI",
            priority: 20,
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
          },
          commons: {
            name: "chunk-commons",
            test: resolve("src/components"),
            minChunks: 3,
            priority: 5,
            reuseExistingChunk: true,
          },
        },
      });
      config.optimization.runtimeChunk("single");
    });
  },
};

마지막으로, main.js에서 아이콘을 포함하도록 설정합니다.

import "./icons";

이제 프로젝트 어디서든 <custom-svg-icon> 컴포넌트를 사용할 수 있습니다.

<span class="svg-container">
  <custom-svg-icon icon="user" />
</span>

태그: Vue.js svg-sprite-loader Webpack

7월 20일 06:06에 게시됨