일도 적응했겠다, 다시 새로운 마음가짐으로, 개발 블로그를 시작해보려 해요! 🎉
최근에 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>
이를 해결하기 위해 다음과 같은 가설을 세웠어요!
- 반응성이 없어진 이유는, return 값에서
value
를 직접 명시해줌으로써 원시 타입으로 전달했기 때문이다.Vue 3
문법에 대한 지식 부족이다. 이를 다른 방법을 찾아 다르게 처리해보아야겠다.
이제 이에 대한 가설을 해결해볼까요? 👀
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>
결과적으로 잘 반영이 되는군요!
이를 위해 공식 문서를 서칭해본 결과...
다음과 같은 방식으로 객체 타입의 자바스크립트 표현식을 처리할 수 있음을 발견했어요 👋🏻
따라서 '관심사가 있는 것들은 객체로 묶어서 관리해야 깔끔하다'고 판단했기에
바로 코드를 바꿨어요! 😉
<script>
const modalStyle = computed(() => ({
display: propsVisible.value ? 'flex' : 'none',
}));
</script>
<style>
.modal__bg {
display: v-bind('modalStyle.display');
...
}
</style>
원하는 로직이었던 Modal
컴포넌트의 display
제어가 잘 되는 것을 확인했어요!
반응성에 미숙했던 제 자신을 되돌아보게 됐어요.
ref
나 computed
등을 통해 획득한 반응성을 value
값을 직접 return 값에 넣음으로써 상태 반응성을 없애버렸던 것에 대해 반성하게 됐어요. 명백한 문법적 미스였습니다. 😂
사실 최근에 Vue
에서도 효과적으로 스타일 변수를 제어하면 좋겠다는 생각을 갖고 있었는데요. Vue 3
역시 CSS-in-JS
라이브러리들 못지 않게 꽤나 괜찮은 문법을 지원한다는 것을 깨달았답니다!
간만에 블로그 글 쓰니 기분이 좋아요. Hello, Velog!