ABOUT ME

-

  • [ Vite + Vue ] Svg Loader, svg 아이콘 컴포넌트
    Front/Vue 2025. 6. 3. 17:14
    반응형

    svg 아이콘을 좀 더 편하게 사용하기 위해

    svg 컴포넌트를 구현

     


    Installment

    vite에서 svg를 사용하기위해서 vite-plugin-svgr을 설치

    npm install vite-plugin-svgr --save-dev

     

    이후 vite.config.ts에서 svgLoader plugin을 등록

    import svgLoader from 'vite-svg-loader'
    
    // https://vite.dev/config/
    export default defineConfig({
      plugins: [vue(), svgLoader()],

    SVG Icon

    우선 svg 아이콘 관리를 위해 constant > icon.ts 파일을 만들어 svg 아이콘을 상수화 작업을 진행

    import calendarIcon from "@/assets/icons/calendar.svg"
    
    export const ICONS = {
        CALENDAR: calendarIcon,
    }

     

     

    Svg 파일에서 색상을 style로 변경을 할 수 있게 하기 위해서 각 path에 있는 stroke를 최상단 svg태그로 옮겨준다.

     

    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#3A3A3A" xmlns="http://www.w3.org/2000/svg">
        <path d="M21.9697 15V9C21.9697 4 19.9697 2 14.9697 2H8.96973C3.96973 2 1.96973 4 1.96973 9V15C1.96973 20 3.96973 22 8.96973 22H14.9697C19.9697 22 21.9697 20 21.9697 15Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
        <path d="M22 8.5H2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
        <path d="M9.44055 12.9399L12.0005 15.4999L14.5605 12.9399" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>

     


    SVG Component

    svg component에서 props로 상수화 시킨 아이콘을 받을 수 있도록 처리하며

    size를 받아 아이콘의 크기를 자유롭게 조절 할 수 있도록 설정

     

    이때 size를 숫자로 받아 처리해도 해당 값으로 width,height를 설정해도 되지만, 여러 아이콘을 사용하다보면 헷갈릴 수 있을 것 같아서

    각 사이즈 별로 px을 미리 세팅하여 적용

     

    대부분의 아이콘을 storke만 사용하여 색을 변경을 할 예정이기에, style에 stroke만 currentColor로 세팅하여 색이 있으면 해당 색으로 대체되도록 적용, 만약 없다면 기본 svg 파일에서 설정한 색으로 나오게된다.

    <script setup lang="ts">
    import {computed} from "vue";
    
    interface Props {
      icon: String
      size?: 'xsmall' |'small' | 'large' | 'big'
    }
    
    const props = withDefaults(defineProps<Props>(), {
      size: 'large'
    })
    
    
    const size = computed(() => {
      switch (props.size) {
        case 'xsmall' :
          return {
            width: '12px',
            height: '12px',
          }
        case 'small':
          return {
            width: '16px',
            height: '16px'
          }
        case 'large' :
          return {
            width: '20px',
            height: '20px'
          }
        case 'big' :
          return {
            width: '24px',
            height: '24px'
          }
      }
    })
    </script>
    
    <template>
      <component :is="props.icon" class="svg-icon" :style="{width: size.width, height: size.height}"
                 v-bind="{ viewBox: '0 0 24 24' }"/>
    </template>
    
    <style scoped lang="scss">
    .svg-icon {
      display: flex;
      align-items: center;
      justify-content: center;
      outline: none;
      fill: transparent;
      overflow: hidden;
      stroke: currentColor;
      cursor: pointer;
    }
    </style>

     

     

    이제 실제 사용은 svg-icon 컴포넌트를 불러와 icon에 사용할 상수화 시킨 아이콘을 넣으면 된다.

    이후 style에서 이전 svg-icon의 storke 색상을 바꾸면 해당 색으로 아이콘의 storke색이 변경

    <script setup lang="ts">
    
    import SvgIcon from "@/components/common/SvgIcon.vue";
    import {ICONS} from "@/constant/icons.ts";
    </script>
    
    <template>
    <div class="app-header-wrapper">
      <svg-icon :icon="ICONS.CALENDAR"/>
    </div>
    </template>
    
    <style scoped lang="scss">
    .app-header-wrapper {
      width: 100%;
      height: 30px;
      padding: var(--app-root-padding);
    
      .svg-icon {
        stroke: red;
      }
    
    }
    </style>

    728x90
    반응형