[Vue 3] computed CSS variable not working

young_pallete·2022년 6월 6일
2

Vue

목록 보기
2/3
post-thumbnail

🔥 배경

일도 적응했겠다, 다시 새로운 마음가짐으로, 개발 블로그를 시작해보려 해요! 🎉

최근에 Vue 3로 마이그레이션을 준비할 겸, 부사수에게 Vue 3 문법을 알려주기 위해 CSS variable 문법을 적용하며 예제를 작성하던 중 오류를 마주했어요.

상태 값을 감시해본 결과, prop의 변경사항은 감지되었으나, 이를 제대로 style에서 reactivity를 감지하지 못하는 문제가 발생한 것이 문제라고 정의했어요.

아래는 문제가 발생한 코드입니다 🥲


<script lang="ts">
export default defineComponent({
  ...

  setup(props, { emit }) {
    const propsVisible = computed(() => props.visible);
    const modalStyle = computed(() => ({
      display: propsVisible.value ? 'flex' : 'none',
    }));

    return {
      modalStyleDisplay: modalStyle.value.display,
      onConfirm,
      onCancel,
    };
  },
});
</script>

<style lang="scss" scoped>
.modal__bg {
  display: v-bind(modalStyleDisplay);
  justify-content: center;
  align-items: center;

  // ...
}
</style>

🌟 해결 과정

🔎 가설 설정

이를 해결하기 위해 다음과 같은 가설을 세웠어요!

  1. 반응성이 없어진 이유는, return 값에서 value를 직접 명시해줌으로써 원시 타입으로 전달했기 때문이다.
  2. Vue 3 문법에 대한 지식 부족이다. 이를 다른 방법을 찾아 다르게 처리해보아야겠다.

이제 이에 대한 가설을 해결해볼까요? 👀

1. 반응성이 없어진 이유는, return 값에서 value를 직접 명시해줌으로써 원시 타입으로 전달했기 때문이다.

일단 왜 이렇게 전달을 했을까요?
저는 객체로 CSS Variables의 상태를 컨트롤 하고 싶었어요. 관심사끼리 객체로 묶어서 상태 값을 관리하면 더욱 깔끔한 코드를 유지할 수 있다고 생각했기 때문이죠.

하지만 이를 제대로 해결할 수 없었고, 결국 다음과 같이 computed를 객체가 아닌 단일 원시 값을 지정함으로써 해결해 보았습니다.

<script lang="ts">
const modalStyleDisplay = computed(() => propsVisible.value ? 'flex' : 'none');
</script>

<style lang="scss" scoped>
.modal__bg {
  display: v-bind('modalStyleDisplay');
  ...
}
</style>

결과적으로 잘 반영이 되는군요!

2. Vue 문법 중 다른 방법을 찾아 다르게 처리해보아야겠다.

이를 위해 공식 문서를 서칭해본 결과...
다음과 같은 방식으로 객체 타입의 자바스크립트 표현식을 처리할 수 있음을 발견했어요 👋🏻

Vue 3 공식문서

따라서 '관심사가 있는 것들은 객체로 묶어서 관리해야 깔끔하다'고 판단했기에
바로 코드를 바꿨어요! 😉

 <script>
   const modalStyle = computed(() => ({
    display: propsVisible.value ? 'flex' : 'none',
  }));
 </script>
    
 <style>
 .modal__bg {
    display: v-bind('modalStyle.display');
    ...
  }
 </style>

🎉 결과

원하는 로직이었던 Modal 컴포넌트의 display 제어가 잘 되는 것을 확인했어요!
동작 테스트 결과

✨ 배운 점

반응성에 미숙했던 제 자신을 되돌아보게 됐어요.

refcomputed 등을 통해 획득한 반응성을 value 값을 직접 return 값에 넣음으로써 상태 반응성을 없애버렸던 것에 대해 반성하게 됐어요. 명백한 문법적 미스였습니다. 😂

사실 최근에 Vue에서도 효과적으로 스타일 변수를 제어하면 좋겠다는 생각을 갖고 있었는데요. Vue 3 역시 CSS-in-JS 라이브러리들 못지 않게 꽤나 괜찮은 문법을 지원한다는 것을 깨달았답니다!

간만에 블로그 글 쓰니 기분이 좋아요. Hello, Velog!

profile
People are scared of falling to the bottom but born from there. What they've lost is nth. 😉

0개의 댓글