프로그래밍/Vue.js

vuejs Renderless Component 패턴 이해하기

p-a-r-k 2024. 12. 20. 13:21
반응형

Renderless Component란?

Renderless Component는 Vue.js에서 컴포넌트의 로직과 표현을 분리하는 패턴이다. 이 패턴은 컴포넌트의 기능을 캡슐화하면서도 시각적인 표현은 제한하지 않는다.. 즉, Renderless Component는 로직과 동작에만 집중하고, 실제 렌더링은 부모 컴포넌트에 맡기는 방식이다.

실제 예제로 이해

Toggle 컴포넌트 만들기

애플리케이션의 여러 부분에서 사용될 수 있는 토글 UI 요소를 생각해보기. 어떤 토글은 버튼으로, 다른 토글은 체크박스나 스위치로 표시될 수 있다.

먼저 기본적인 renderless 토글 컴포넌트를 만들어보면 다음과 같다:

<!-- RenderlessToggle.vue -->
<template>
  <slot :isActive="isActive" :toggle="toggle"></slot>
</template>

<script setup>
import { ref } from "vue";

const isActive = ref(false);

const toggle = () => {
  isActive.value = !isActive.value;
};
</script>

 

이제 이 renderless 컴포넌트를 사용하여 세 가지 다른 스타일의 토글을 만들어보면 다음과 같다:

<template>
  <!-- 스위치 스타일 토글 -->
  <RenderlessToggle v-slot="{ isActive, toggle }">
    <div class="toggle-wrapper">
      <label class="switch-control">
        <input type="checkbox" :value="isActive" @click="toggle" />
        <div class="switch-slider" :class="isActive ? 'active' : ''"></div>
      </label>
    </div>
  </RenderlessToggle>

  <!-- 버튼 스타일 토글 -->
  <RenderlessToggle v-slot="{ isActive, toggle }">
    <div class="toggle-wrapper">
      <button class="toggle-btn" @click="toggle">
        상태: <span>{{ isActive ? "켜짐 ✨" : "꺼짐 💤" }}</span>
      </button>
    </div>
  </RenderlessToggle>

  <!-- 탭 스타일 토글 -->
  <RenderlessToggle v-slot="{ isActive, toggle }">
    <div class="toggle-wrapper">
      <button
        :class="['tab-btn', { active: isActive }]"
        @click="toggle"
      >
        On
      </button>
      <button
        :class="['tab-btn', { active: !isActive }]"
        @click="toggle"
      >
        Off
      </button>
    </div>
  </RenderlessToggle>
</template>

<script setup>
import RenderlessToggle from './RenderlessToggle.vue';
</script>

<style scoped>
.toggle-wrapper {
  margin: 1rem;
}

.switch-control {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch-slider {
  position: absolute;
  cursor: pointer;
  background-color: #ccc;
  border-radius: 34px;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  transition: .4s;
}

.switch-slider.active {
  background-color: #2196F3;
}

.toggle-btn {
  padding: 8px 16px;
  border: 2px solid #2196F3;
  border-radius: 4px;
  cursor: pointer;
}

.tab-btn {
  padding: 8px 16px;
  border: 1px solid #ddd;
  background: white;
  cursor: pointer;
}

.tab-btn.active {
  background: #2196F3;
  color: white;
}
</style>

 

Renderless Component의 장점

  1. 로직 재사용: 동일한 로직을 여러 다른 UI 구현에서 재사용할 수 있다.
  2. 관심사 분리: 비즈니스 로직과 UI 표현을 깔끔하게 분리할 수 있다.
  3. 유연성: 동일한 로직에 대해 다양한 시각적 표현을 구현할 수 있다.

Composables vs Renderless Components

Vue.js에서는 로직을 재사용하는 두 가지 주요 패턴이 있는데..:

  1. Composables: 함수 기반으로 반응형 데이터와 메서드를 반환하며, 여러 컴포넌트에서 임포트하여 사용할 수 있다.
  2. Renderless Components: 컴포넌트의 로직을 분리하고 렌더링을 부모 컴포넌트에 위임한다.

Vue.js 공식 문서에서는 가능한 한 Composables를 사용하는 것을 권장한다.

Renderless Component 패턴은 추가적인 컴포넌트 인스턴스가 생성되어 성능 오버헤드가 발생할 수 있기 때문이다.

하지만 렌더링에 대한 세밀한 제어가 필요하거나 로직과 시각적 레이아웃을 모두 재사용해야 하는 상황에서는 Renderless Component가 유용할 수 있다..

반응형

'프로그래밍 > Vue.js' 카테고리의 다른 글

vuejs Render Function 이해하기  (1) 2024.12.20
vuejs 반응형 sprite canvas 만들기  (1) 2023.07.19
vuejs 슬롯머신 만들기  (0) 2023.05.22
vuejs 룰렛만들기  (0) 2023.05.22
vuejs 가상스크롤로 로딩지연 개선  (1) 2023.02.27