FrameWorks/Vue

VueRouter의 RouterView Slot 파헤치기

ABCD 2024. 7. 29.

RouterView slot

<router-view>v-slot을 사용하여 특정 컴포넌트를 유연하게 조작할 수 있습니다.

<router-view v-slot="{ Component }">
    <component :is="Component" />
</router-view>

 

위의 코드는 평소에 사용하는 <router-view />코드와 동일하게 동작합니다.
위의 코드를 활용해서 유연하게 조작하는 것이지요. 살펴보도록 할까요??

KeepAlive

<router-view>태그 안에 <keep-alive>를 넣어 사용하는 방법입니다.
<keep-alive>태그로 감싸면 해당 컴포넌트는 리렌더링 하지 않겠다는 뜻입니다.

 

그럼 리렌더링을 하지 않으면 어떻게 될까요??

 

만약 데이터를 변경시키고 다른 컴포넌트로 이동 후 다시 돌아왔을 대 데이터가 유지되어 있을 겁니다.

 

아래와 같이 사용합니다.

<router-view v-slot="{ Component }">
    <keep-alive>
        <component :is="Component" />
    </keep-alive>
</router-view>

<!-- 또는 Component를 직접 바인딩 할 수도 있습니다.-->
<router-view>
    <keep-alive>
        <!-- script 에서 컴포넌트 바인딩 -->
        <component :is="Component" />
    </keep-alive>
</router-view>

Transition

<router-view>태그 안에 <transition>를 넣어 사용하는 방법입니다.
<transition>태그로 감싸 하위의 컨텐츠에 트랜지션 or 애니메이션을 넣을 수 있습니다.

<router-view v-slot="{ Component }">
    <transition name="foo">
        <component :is="Component" />
    </transition>
</router-view>

<!-- 또는 Component를 직접 바인딩 할 수도 있습니다.-->
<router-view>
    <transition name="foo">
        <!-- script 에서 컴포넌트 바인딩 -->
        <component :is="Component" />
    </transition>
</router-view>

 

단, 애니메이션 작업은 직접 CSS를 사용하여 만들어 주어야 합니다.

바로 CSS 기반 트랜지션인거죠.

 

이 태그의 좋은 점은 CSS를 작성할 때 class를 지정해서 작업하지 않고 <transition>name속성으로 class를 따라갑니다.

위의 컴포넌트로 예를 들어보겠습니다.


<transition>태그에 name속성의 값으로 foo를 선언했습니다.
그러면 foo-enter-active의 class로 CSS를 작업하면 되는 겁니다.

 

이렇게 되면 선언한 class는 없지만 랜더링시 다음과 같이 6개의 class가 부여됩니다.

  • ${transition-name}-enter-from
    • 진입 시작 상태
    • 요소가 삽입되기 전에 추가되며, 삽입된 후 1초후에 삭제 됩니다.
  • ${transition-name}-enter-active
    • 진입 활성 상태
    • 모든 진입상태에 적용됩니다.
    • 삽입되기 전에 추가되고, 트랜지션 or 애니메이션이 끝나면 삭제됩니다.
    • 진입 트랜지션에 대한 지속 시간, 딜레이 및 이징(easing)곡선을 정의하는데 사용할 수 있습니다.
  • ${transition-name}-enter-to
    • 진입 종료 상태
    • 엘리먼트가 삽입된 후 1프레임 후 추가되고(동시에 ${transition-name}-enter-from이 제거됨), 트랜지션 or 애니메이션이 끝나면 삭제됩니다.
  • ${transition-name}-leave-from
    • 진출 시작 상태
    • 진출 트랜지션이 트리거되면 즉시 추가되고 1프레임 후 제거됩니다.
  • ${transition-name}-leave-active
    • 진출 활성 상태
    • 모든 진출상태에 적용됩니다.
    • 진출 트랜지션이 트리거되면 즉시 추가되고, 트랜지션 or 애니메이션이 끝나면 삭제 됩니다.
    • 진출 트랜지션에 대한 지속시간, 딜레이 및 이징(easing)곡선을 정의하는데 사용할 수 있습니다.
  • ${transition-name}-leavte-to
    • 진출 종료 상태
    • 진출 트랜지션이 트리거된 후 1프레임이 추가되고(동시에 ${transition-name}-leave-from이 제거됨), 트랜지션 or 애니메이션이 끝나면 삭제됩니다.

KeepAlive & Transition

<keep-alive>transition은 중첩해서 사용 할 수 있습니다.

<router-view v-slot="{ Component }">
    <transition>
        <keep-alive>
            <component :is="Component" />
        </keep-alive>
    </transition>
</router-view>

Passing props and slots

일반적으로 vue에서 사용하는 방법이랑 동일합니다.
해당 <router-view>에서 계속 가지고 다녀야하는 데이터를 컨트롤할 때 좋겠죠??
태그에는 캐밥케이스로 데이터 가져다 쓸 자식에서는 카멜케이스를 사용합니다.

<router-view v-slot="{ Component }">
    <component :is="Component" some-prop="a value">
        <p>Some slotted content</p>
    </component>
</router-view>

Template refs

Vue에서는 선언적 렌더링 모델은 개발자가 직접 DOM에 접근해야 하는 대부분을 추상화하지만, DOM 엘리먼트에 직접 접근해야하는 경우가 있습니다.

이럴경우 태그의 ref속성을 이용하여 접근하게 됩니다.
이는 JQuery의 엘레먼트에 접근하는것과 비슷하다고 생각하면 됩니다.

$('#id') or $('.class')

단, 몇가지 조건이 있습니다.

  • 컴포넌트가 마운트된 후에만 ref에 접근할 수 있습니다.
  • 태그에 선언한 ref속성 값이 변수명과 일치해야 합니다.
  • 마운트 후 속성 값인 변수명에 데이터가 채워지는 방식이므로 타입이 같아야한다.
<script setup>
import { ref, onMounted } from 'vue'

// 엘리먼트 참조를 위해 ref를 선언
// 이름은 템플릿 ref 값과 일치해야 함
const inputRef = ref(null) // 여기에 바인딩
const input - ref(null) // 여기에 바인딩되지 않음

onMounted(() => {
    input.value.focus()
})
</script>

<template>
    <input ref="inputRef" />
</template>

 

만약 refv-for내부에서 사용된다면???
해당 ref는 마운트 후 엘리먼트로 채워지기 때문에 타입이 같아야합니다.


단, ref의 배열은 소스 배열과 동일한 순서를 보장하지 않습니다.

<script setup>
import { ref, onMounted } from 'vue'

const list = ref([
    /* ... */
])

const itemRefs = ref([])

onMounted(() => console.log(itemRefs.value))
</script>

<template>
    <ul>
        <li v-for="item in list" ref="itemRefs">
            {{ item }}
        </li>
    </ul>
</template>
728x90
반응형

댓글

💲 추천 글