728x90
Vue로 개발을 진행하다 보면 기존과 약간 다른 개발 방식에 애매한 상황이 생긴다.
그 중 하나로 Vue의 데이터와 화면의 UI를 찾아 접근해야 하는 상황에서 DOM을 찾지 못하는 상황이 있다.
데이터를 통해서 만들어지게 되는 DOM이 완성되기 이전 시점에 호출을 하려고 하는 상황인데, 어떠한 데이터를 변수에 담아 화면이 갱신되는 DOM에 바로 접근하려고 하면 DOM 요소가 없다는 에러를 뱉는다.
💡 예시코드
<template>
<div>
<button @click="showInput">show Input<button>
<input ref="input_box" v-show="isShow"/>
</div>
</template>
<script>
export default {
data() {
return {
isShow: false,
}
}
methods: {
showInput() {
this.isShow = true;
// "Uncaught TypeError: Cannot read property 'focus' of undefined"
this.$refs.input_box.focus();
}
}
}
</script>
모든 데이터 처리가 비동기로 처리되는 자바스크립트 특성 때문에 DOM이 갱신되기 전 탐색하는 상황에서 생기는 현상이다. 그래서 setTimeout을 이용해 약간의 시간차를 주게되면 문제없이 DOM에 접근 할 수 있게 된다.
<script>
// ...
showInput() {
this.isShow = true;
setTimeout(() => {
this.$refs.input_box.focus();
}, 300) // 0.3초 딜레이
}
그런데 웹뷰를 사용하는 입장에서 IOS의 setTimeout은 여러 이슈가 많다.... = 안된다 ㅂㄷㅂㄷ
사실 IOS 문제 뿐만 아니라 시간의 갭을 활용해서 쓰는 setTimeout은 좋지 않은거 같기도 하다.
그럴때 사용할 수 있는 callback함수 $nextTick
<script>
// ...
showInput() {
this.isShow = true;
this.$nextTick(() => {
this.$refs.input_box.focus();
})
}
코드를 $nextTick으로 감싼뒤 callback을 통해 DOM에 접근한다. 그렇게 되면 vue에서 데이터를 갱신하고 화면 UI 렌더링까지 완료된 후 nextTick의 콜백이 실행되고 DOM으로 접근하는 과정을 거치게 된다.
728x90
'FRONTEND > Vue.js' 카테고리의 다른 글
[Vue] arrow function 사용 시 주의 사항 (0) | 2023.05.17 |
---|---|
[Vue] vuex의 mutations과 actions (0) | 2023.05.16 |
[Vue] vuelidate를 사용하여 폼 검증하기 (Vue2) (0) | 2023.04.13 |
[Vue] 카드번호 자동 하이픈(-) 정규식 (0) | 2023.04.13 |
[ERROR] NavigationDuplicated: Avoided redundant navigation to current location (0) | 2023.03.17 |