vuejs compute method watch 사용법
vue.js 에서
computed
, method
, watch
data
data: function(){...} 는 처음에 component 가 init 될 때 한번 호출된다. 그후엔 호출되지 않는다. 그러기에 watch 같은 것을 이용해서 computed 같은 효과를 주는 듯 하다.
computed vs method 사용법
기본적으로 rendering 이 될 때 template 안에서 사용되는 computed,
methods 를 호출하게 된다. template 안에서 사용되지 않는 함수(computed,
methods)라면 당연히 호출되지 않는다.
다음처럼 computed property
와 method
가
있다. 아래 같은 상황에서 2개는 똑같은 결과를 보여준다. 하지만 동작의
차이는 있다.
computed
는 그 ‘안에서 사용된 property’ 가 변할 때만
함수를 호출한다. 만약 ‘안에서 사용된 property’ 가 변하지 않았으면 값이
바뀌지 않을 것으로 판단하고, 이전의 값을 그대로 돌려준다.(computed
properties are cached based on reactive dependencies)
하지만 ‘안에서 사용된 property’가 바꼈는지 상관없이 method 는 모조건
호출된다. 그래서 아래 코드에서 Date.now() 의 호출은
calculateBooksMessage
에서는 ’안에서 사용된 property’ 가
변할 때만 호출되지만, calculateBooksMessage2
는 항상
호출된다.
<p>{{ calculateBooksMessage }}</p>
<p>{{ calculateBooksMessage2() }}</p>
Vue.createApp({
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// a computed getter
calculateBooksMessage() {
// `this` points to the vm instance
const now = Date.now()
return this.author.books.length > 0 ? 'Yes' + now : 'No'
}
},
method: {
calculateBooksMessage2() {
const now = Date.now()
return this.author.books.length > 0 ? 'Yes' + now : 'No'
}
}
}).mount('#computed-basics')
watch property
computed property
는 data 와 같은 것이라 봐도 무방하다.
그래서 2개는 내가 사용하고 싶은 data 를 선언하는 것이라고 보면 된다.
그런데 만약 이미 선언되어 있는 data 에 대해서 내가 그 데이터가 변할때 어떤 작업을 하도록 하고 싶다. 즉, 그 data가 변할 때 reactive 하게 무엇인가를 하고 싶다면 그 data 에 대해서 watcher 를 선언하면 된다.
그래서 watcher 의 key 이름은 우리가 observe 하려는 것의 이름을 가져야
한다. 그래서 만약 위처럼 calculateBooksMessage
를
사용하려면, 이 이름을 가진 data 가 존재해야 하고, 그 data 에 대한 watch
를 선언하는 것이다.
<p>{{ calculateBooksMessage }}</p>
<p>{{ calculateBooksMessage2() }}</p>
Vue.createApp({
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
},
calculateBooksMessage: 'cal-message'
}
},
watch: {
// a computed getter
calculateBooksMessage: function() {
// `this` points to the vm instance
const now = Date.now()
return this.author.books.length > 0 ? 'Yes' + now : 'No'
}
},
}).mount('#computed-basics')
object 와 array값이 변경될 때 reactivity
자세한 이야기는 위 링크를 참고하자. 대략적으로 정리하면, array 값이
변경될 때는 splice
를 사용해야 인식한다. object 는
Object.assign({}, ...)
을 사용하던지,
this.$set(this.someObject, 'b', 2)
를 사용해야 한다.
vue3 에서는 reactivity 의 breaking 에 대한 걱정을 하지 않아도 된다고 한다.(참고: vue.js - How do I do Vue.set() in Vue 3? - Stack Overflow)
ReactJS의 setState
개인적으로는 react 의 setState 를 호출하는 방식이 좀 더 명확해서 좋다. vuejs 는 대체로 스스로 알아서 setState 를 호출하는 식이긴 한데, 이것이 명확하게 보이지 않아서 개인적으로 debugging 하기가 힘들다.
여하튼, 그래서 vuejs 를 setState 을 호출하는 느낌으로 설명을 하자면, rendering 이 필요할 때 react 에서 setState 를 호출하는 것처럼 vuejs 에서는 <template> 안에서 사용되는 property 를 변경해야 한다. 그러니까 반대로 react 에서 setState 를 호출해야 하는 순간이라면 property 값을 변경하는 과정이 있으면 된다.
참고로, reactjs 처럼 key 를 변경해서 re-render 를 하게 하는 방법도 가능하다.
key 를 이용해서 re-render 를 지시할 때 주의할 점
key가 변경되는 element 에 대한 rendering 을 다시할 때 그 element 의
props 를 새롭게 받아오지는 않는다는 것이다. key 를 가진 element 의 기존
props 를 이용해서 그 element 의 render() 를 호출한다. 만약 props
를 다시 받아서 rendering 을 해야 한다면, 그 부모 element 의 key 를
변경해야 한다.
댓글 없음:
댓글 쓰기