본문 바로가기

FrontEnd

[Vue3] props와 컴포넌트 상태 동기화

반응형

Vue3에서 컴포넌트의 상태와 외부 props 값을 동기화 하는 방법을 알아봅니다.

Vue3

TL;DR

  • props은 기본적으로 readOnly인 reactive 값임
  • 기본값을 reactive하게 선언
  • 내부적으로 사용할 상태를 computed로 선언하여 props 여부에 따라 활용 여부 결정

useControllable 컴포저블

해당 함수는 headlessUI 깃헙에서 가져옴

사용처에서는 아래와 같이 활용함.

    let [checked, theirOnChange] = useControllable(
      computed(() => props.modelValue), // props를 활용한 computed
      (value: boolean) => emit('update:modelValue', value), // 값 변경 시 호출활 콜백
      computed(() => props.defaultChecked) // default값을 활용한 computed
    )

내부 구현은 다음과 같음 (use-controllable.ts)

import { computed, ComputedRef, UnwrapRef, ref } from 'vue'

export function useControllable<T>(
  controlledValue: ComputedRef<T | undefined>,
  onChange?: (value: T) => void,
  defaultValue?: ComputedRef<T>
) {
  let internalValue = ref(defaultValue?.value)
  let isControlled = computed(() => controlledValue.value !== undefined)

  return [
    computed(() => (isControlled.value ? controlledValue.value : internalValue.value)),
    function (value: unknown) {
      if (isControlled.value) {
        return onChange?.(value as T)
      } else {
        internalValue.value = value as UnwrapRef<T>
        return onChange?.(value as T)
      }
    },
  ] as const
}

@change와 같은 핸들러에 theirOnChange로 전달되는 함수를 사용하면 됨

예제 코드 및 실행해보기

 

Vue SFC Playground

 

sfc.vuejs.org

 

 

반응형