전달인자
Object
, Function
비동기로 처리되는 javascript의 특성상 data가 업데이트 되고 난 직후 UI 갱신 시 vue가 DOM을 찾지 못하는 경우가 있다. 이때 callback 함수인
$nextTick()
을 사용한다.
$nextTick()
의 콜백함수 안에서 DOM을 조작하면, 데이터를 가지고 화면을 그리기 전에 DOM이 먼저 생성되어 트리를 찾지 못하는 오류를 막을 수 있다.
예시 1
<template>
<div id="app">
<div v-for="item in list" :key="item">
<div :id="bindId(item)"/> <!-- 2 -->
</div>
</div>
</template>
<script>
export default {
data () {
return {
list: []
};
},
created () {
for (let i = 0; i < 100; i++) {
this.list.push(i); // 1
}
const dom = document.getElementById('item-0'); // DOM을 찾지 못해 에러발생
dom.style.backgroundColor = 'red';
},
methods: {
bindId (item) {
return 'item-' + item; // 3
}
}
};
</script>
이 때 $nextTick()
을 사용함으로서 data 갱신과 UI를 그린 후 실행되어 dom.style.backgroundColor = 'red';
적용한다.
this.$nextTick(function () {
const dom = document.getElementById('item-0');
dom.style.backgroundColor = 'red';
});
다만 UI가 그려질 때 까지 dom.style.backgroundColor = 'red';
가 실행되지 않기 때문에 일정 지연이 발생한다.
예시 2
<template>
<div class="hello">
{{ msg }}
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'One'
};
},
mounted () {
this.msg = 'Two';
this.$nextTick(() => {
this.msg = 'Three';
});
}
};
</script>
mounted
에 선언된 Two
는 화면에 그려질까? 아니다.
One
과 Three
만 그려진다. 그 이유는 data
가 실행되고 브라우저에 권한을 넘겨주는 대신 바로 callback
이 실행되기 때문에 Two
는 그려지지 않는다.
But with
nextTick
, we skip steps 2 and 3! Instead of passing over control after the first vDOM update, Vue calls the callback immediately
, which prevents the browser from updating until the callback is finished. In this example, that means "Two" is never actually displayed.
$forceUpdate
Vue의 상태는 변경되었으나 화면에 변경된 상태가 반영되지 않는 경우 이 메서드를 사용하며 다시 렌더링하며 반영시킬 수 있다.하지만 렌더링은 작업 자체가 비용이 많이 들기 때문에 과도하게 사용할 시 애프리케이션의 성능이 하락할 수 있다.
<div id="app">
<h1>{{Math.random()}}</h1>
<button @click="update">Force Update</button>
</div>
methods:{
update(){
this.$forceUpdate();
}
}