728x90

JavaScript와 HTML, CSS등에 대해서는 일체 다루지 않는다.

기초지식은 다른 강의를 참조하도록 하라.


참고:

[Package]Bower(Front End Pacakage 관리) 설치

[Package]Vue.js


일반적으로 자바스크립트코드를 직접적으로 수정한다고해서 무조건 재렌더링 된다는 보장은 없다.

우리가 특정변수를 직접 바꾸는 경우에 재렌더링이 실행되나 배열과 Object는 그렇지 않은 사례가 있다.


일단 결과와 해결책 부터 말해줄것이다.

그리고 아래의 예제를 보면서 왜 그런지에 대해서 찬찬히 알아보자.


JS값이 바뀌어도 재랜더링이 되지 않는 이유

vue의 값의 변화는 "객체의 변화"를 감지한다. 즉 객체 자체가 바뀌는건 감지한다. 그러나 객체의 속성, 배열의 값이 바뀌는건 감지하지 못한다.

이를 해결하는 방법은 배열의 경우 배열 내부의 함수들을 사용하는 것이다.


ex)splice, slice, push 등...


Object의 경우 이러한 함수들이 없다. 그래서 this.$set 메소드를 이용해줘야한다.


this.$set(<변수 명>,<변수 타입>,<값>)


ex) this.$set(person1, 'name', 'Jhone')



이렇게 배열의 메소드들이나 this.$set을 사용하면 vue는 이의 변화를 알아보고 재랜더링하게 된다.



아래의 코드를 보자.

<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="setArrayLength">setArrayLength</button>
<ul>
<li v-for="value in arr">
<td>{{value}}</td>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr : [1,2,3,4,5,5]
},
methods:{
setArrayLength:function () {
this.arr.length = 3;
console.log(this.arr)
}
}
});
</script>
</html>

현재 배열의 크기는 6이다.

만약 버튼을 누른다면 배열의 크기는 3이고 나머지는 짤리게 된다.

이 경우 다시 렌더링이 될까?

한번 확인해보자.



보다시피 배열의 크기가 변화하였지만 실제로 렌더링이 다시 실행되지 않았다.

그 이유는 배열의 값이 변화하는걸로는 렌더링이 실행되지 않기 때문이다.

정확하게 말하면 배열이던 객체건 간에 레퍼런스 그 자체가 바뀌어야 변화를 감지하는데 내부의 값(Object의 경우 속성)이 바뀌는건 감지하지 못한다.

그래서 다시 렌더링이 되려면 vue에서 몇가지 함수들을 변화를 감지할 수 있도록 래핑해두었는데 그중에서 splice를 사용해야 한다.


<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="setArrayLength">setArrayLength</button>
<ul>
<li v-for="value in arr">
<td>{{value}}</td>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr : [1,2,3,4,5,5]
},
methods:{
setArrayLength:function () {
this.arr.splice(3);
console.log(this.arr)
}
}
});
</script>
</html>

단 한줄이 바뀌었다. splice를 사용하면된다.



보다시피 제대로 렌더링되는것을 알 수있다.

만약 배열의 크기를 바꾼다면 이때는 splice를 사용해주자.


<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="setArrayLength">setArrayLength</button>
<ul>
<li v-for="value in arr">
<td>{{value}}</td>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4, 5, 5]
},
methods: {
setArrayLength: function () {
this.arr[3] = undefined;
}
}
});
</script>
</html>

만약 배열을 하나 삭제한다면 어떻게 할까?

가장 쉬운방법은 하나를 undefined해주는 것이다.



그러나 보다시피 초기화가 되지 않는다.

이 역시 splice를 통해서 제거해 줄 수 있다.


<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="setArrayLength">setArrayLength</button>
<ul>
<li v-for="value in arr">
<td>{{value}}</td>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4, 5, 5]
},
methods: {
setArrayLength: function () {
this.arr.splice(3, 1, undefined);
}
}
});
</script>
</html>

이 코드를 사용한 결과는 이제 여러분들도 예측할 수있다.



여러분들이 예상한대로  삭제할 수있다.

만약 저기에 undefined말고 다른 값을 넣는다면 값을 대체할 수도 있다.


그래서 결론을 이야기하자면 배열을 관리할때 재 렌더링 시키고싶다면 splice를 사용해야한다는 것이다. 



'Programming > JavaScript-Vue' 카테고리의 다른 글

[Vue-09]이벤트 수식어  (0) 2018.02.23
[Vue-08]이벤트  (0) 2018.02.20
[Vue-06]반복문(v-for)  (0) 2018.02.20
[Vue-05]조건문  (0) 2018.02.20
[Vue-04]데이터 바인딩  (0) 2018.02.20

+ Recent posts