본문 바로가기

FrontEnd

[번역] Vue3 Coding Better Composables : ref 및 unref를 사용하여 유연한 컴포저블 만들기

반응형

prop의 ref 여부와 관계없이 유연하게 사용할 수 있는 컴포저블을 만들어 봅시다.

해당 글을 번역 및 요약한 글입니다.

https://www.vuemastery.com/blog/coding-better-composables-2-of-5/

 

Coding Better Composables: Flexible Arguments (2/5) | Vue Mastery

This tutorial series will serve as your guide on how to craft solid composables that you and your team can rely on.

www.vuemastery.com

이전 시리즈도 참고하세요

2022.12.08 - [Vue.js] - [번역] Vue3 Coding Better Composables : 옵션 객체 파라미터 활용하여 컴포저블 잘 만들기

 

[번역] Vue3 Coding Better Composables : 옵션 객체 파라미터 활용하여 컴포저블 잘 만들기

컴포저블을 잘 활용하여 클린한 Vue3 코드를 작성해 봅시다. 해당 게시물에서는 파라미터를 잘 설계하는 방법을 다룹니다. 컴포저블이란? 상태 저장 로직을 캡슐화하고 재사용하기 위해 Vue Composi

itchallenger.tistory.com


컴포저블을 사용할 때, 때때로 이미 사용할 ref가 있을 경우가 있습니다.

물론 없을 때도 있구요

 

이 아티클 에서는 어느 쪽이든 컴포저블을 사용할 수 있는 패턴을 이용해,
애플리케이션을 작성할 때 더 많은 유연성을 제공하는 방법을 알아봅니다.


보다 유연한 매개변수를 위해 ref 및 unref 사용

때때로 prop은 js primitive, object이거나 뷰의 반응형 객체입니다.

우리는 프롭 타입과 무관하게 컴포저블을 훨씬 더 유연하고 재사용 가능하도록 작성하고 싶습니다.

 

ref 또는 프리미티브를 요구하는 대신 둘 중 하나를 수락할 수 있습니다.
그런 다음 인수를 즉시 필요한 것으로 변환합니다.

// Works if we give it a ref we already have
const countRef = ref(2);
useCount(countRef);

// Also works if we give it just a number
const countRef = useCount(2);

이전 기사에서 본 useTitle 컴포저블도 이 패턴을 적용합니다.
ref를 전달하면 ref의 값이 document의 title에 연결됩니다.

즉 title의 값이 바뀌면 document의 title도 바뀝니다.

const title = ref('This is the title');
useTitle(title);
title.value = 'New title please';
문자열만 전달하면 새 참조가 생성된 다음 document title에 연결됩니다.
const title = useTitle('This is the title');
title.value = 'New title please';

이와 같이 컴포저블을 개발하는 방법을 알아봅시다!


유연한 인수를 허용하는 컴포저블 구현

유연한 인수 패턴이 작동하도록 하려면 인수에 ref 함수 또는 unref 함수를 사용해야 합니다.
// When we need to use a ref in the composable
export default useMyComposable(input) {
  const ref = ref(input);
}

// When we need to use a raw value in the composable
export default useMyComposable(input) {
  const rawValue = unref(input);
}

ref 함수는 우리를 위해 새로운 ref를 생성합니다.

하지만 파라미터로 ref를 전달하면 해당 ref를 반환합니다.

// Create a new ref
const myRef = ref(0);

// Get the same ref back
assert(myRef === ref(myRef));

unref 함수는 유사하게 동작합니다
ref를 풀거나 primitive를 그대로 돌려줍니다.

// Unwrap to get the inner value
const value = unref(myRef);

// Returns the same primitive value
assert(value === unref(value));

VueUse 라이브러리 예제로 사용 사례를 확인해 봅시다.


useTitle

ref, string 아무거나 전달할 수 있습니다.
// Pass in a string
const titleRef = useTitle('Initial title');

// Pass in a ref of a string
const titleRef = ref('Initial title');
useTitle(titleRef);
소스코드(source code)를 보면 내부에서 신규 ref를 만들어 리턴하거나 전달받은 ref를 리턴하는 것을 볼 수 있습니다.
// ...
const title = ref(newTitle ?? document?.title ?? null)
// ...

newTitle의 타입을 보면 좀 더 명확합니다.(the type is defined as)

type MaybeRef<T> = T | Ref<T>

useCssVar

useCssVar컴포저블을 활용하면 CSS 변수의 값을 앱에서 사용할 수 있습니다.

CssVar값은 Css에서 사용하려면 문자열(primitive)이어야 편하겠죠?

인수 타입과 관계없이 문자열을 리턴해 줍니다.

// Using a string
const backgroundColor = useCssVar('--background-color');

// Using a ref
const cssVarRef = ref('--background-color');
const backgroundColor = useCssVar(cssVarRef);

소스 코드(source code)를 보면 이를 수행하기 위해 unref 함수를 사용하고 있음을 알 수 있습니다.
unrefElement라는 도우미 함수를 사용하여 Vue 인스턴스가 아닌 DOM 요소를 가져오고 있는지 확인합니다.

https://github.com/vueuse/vueuse/blob/e484c4f8e4320ff58da95c2d18945beb83772b72/packages/core/unrefElement/index.ts

/**
 * Get the dom element of a ref of element or Vue component instance
 *
 * @param elRef
 */
export function unrefElement<T extends MaybeElement>(elRef: MaybeElementRef<T>): UnRefElementReturn<T> {
  const plain = unref(elRef)
  return (plain as VueInstance)?.$el ?? plain
}

결론

인자 타입(뷰의 반응형 객체, JS 네이티브 타입)에 무관하도록 API를 설계합시다.

리턴 값은 쓰기 편한 타입(뷰의 반응형 객체, JS 네이티브 타입)으로 API를 설계합시다.

반응형