특정 데이터를 입맞에 맞게 가공하여 화면에 보여지게 하는데 유용
<div id="app">
<ul>
<li v-for="todo in upperTodos">{{todo.title}}</li>
</ul>
</div>
const App = {
data() {
return {
todos: [],
};
},
computed: {
upperTodos() {
return this.todos.map((todo) => ({
...todo,
title: todo.title.toUpperCase(),
}));
},
},
created() {
fetch("https://jsonplaceholder.typicode.com/todos")
.then((res) => res.json())
.then((res) => {
console.log(res);
this.todos = res;
});
},
};
const vm = Vue.createApp(App).mount("#app");
메소드로도 이런 기능을 구현할 수 있지만 Vue에서는 가공한 데이터를 보여줄 때는 computed옵션을 권장한다.
computed를 통해 만든 계산된 데이터는 캐싱이라는 기능을 통해서 한 번 연산해놓은 값을 반복적으로 출력할 때 다시 한번 연산하지 않는다. 왜냐하면 저장되어 있는 캐싱된 값으로 그대로 해당하는 내용을 화면에 출력하는 것이 가능하기 때문이다.
<ul>
<li v-for="todo in upperTodos">{{todo.title}}</li>
</ul>
<ul>
<li v-for="todo in upperTodos">{{todo.title}}</li>
</ul>
기존의 반복문에는 배열을 200개 가져와서 뿌려줬다면 이제는 400개를 뿌려줘야하는데 처음 계산된 upperTodos값이 캐싱되어 그 이후 ul태그에서는 연산을 하지 않고 그대로 뿌려주기만 하는 최적화를 한다.
또한, computed내부에 종속되어 있는 데이터의 변화가 있을때만 안의 함수가 실행된다. 이러한 의존성을 바탕으로 렌더링시 최적화를 할 수 있다.
반응형 데이터를 감시해 데이터가 바뀌면 watch내의 함수를 실행하도록 가능
watch:{
firstName() {
console.log(변화)
}
}
감시하고 싶은 데이터를 동일한 이름으로 watch내부에 생성하면 된다.
watch: {
firstName(newValue, oldValue) {
console.log(newValue, oldValue);
},
},
또한, 특정 데이터에 변화를 줬을때, 두 인자를 통해 변하기 전의 값과 변한 후의 값을 참조할 수 있다.
<div id="app">
<h1>{{user.age}}</h1>
</div>
const App = {
data() {
return {
user: {
name: "Leon",
age: 22,
},
};
},
watch: {
user(newValue, oldValue) {
cosnole.log(newValue, oldValue);
},
},
};
const vm = Vue.createApp(App).mount("#app");
하지만, 주의할 점은 감시하는 값이 객체인데 객체의 속성을 바꿨을 경우는 변화를 감지하지 못한다. 즉, 객체를 직접 바꿔줘야 변화를 감지하는 것이다.
따라서, 원시 데이터를 감시하는데는 유용하지만 배열, 객체와 같은 참조형 데이터를 감시하는데는 활용도가 떨어진다.
Deepcopy가 있듯이 Vue에서도 비슷한 기능을 제공하여 위와 같은 문제를 해결해준다.
watch: {
user: {
handler(newValue, oldValue) {
console.log(newValue, oldValue);
},
deep: true,
},
},
handler함수는 변화가 일어났을때 작동하는 함수이고, user를 정의할 때 반드시 함수가 아닌 객체 리터럴로 정의해야한다.
Deep 옵션을 true로 설정하여 이제는 객체내의 속성만 변화시켜도 객체의 변화를 감지할 수 있게 된다.
핸들러함수가 데이터가 바뀔 때가 아니라 페이지가 처음 열렸을 때부터 동작하도록 할 수 있다.
watch: {
user: {
handler(newValue, oldValue) {
console.log(newValue, oldValue);
},
deep: true,
immediate: true,
},
},