JavaScript와 HTML, CSS등에 대해서는 일체 다루지 않는다.
기초지식은 다른 강의를 참조하도록 하라.
참고:
아래와 같은 상황이 있다고 가정해보자.
<!--App.vue-->
<template>
<div id="app">
<Person :name="name"></Person>
<input type="text" v-model="name">
</div>
</template>
<script>
import Person from "./components/Person";
export default {
name: 'App',
components: {Person},
data() {
return {
name: 'Tomato Apple',
}
},
methods:{
}
}
</script>
<style scoped>
</style>
<!--Person.vue-->
<template>
<div class="person">
first name : {{name.split(' ')[0]}}<br>
last name : {{name.split(' ')[1]}}<br>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
name:{}
},
data() {
return {
}
},
created: function () {
},
methods: {},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
내가 받은 입력을 받아서 앞부분은 이름, 뒷 부분은 성으로 취급하려고 한다고 가정해보자.
그러면 여러분은 위처럼 짤 수 있다.
first name : {{name.split(' ')[0]}}<br>
last name : {{name.split(' ')[1]}}<br>
문제는 이런 코드는 직관성을 꽤 해친다고 할 수 있다.
전혀 직관적이지 않는다.
이래서 여러분은 두가지의 해결책을 제시할 수 있다.
1.메소드를 사용해서 해결합시다.
<!--Person.vue-->
<template>
<div class="person">
first name : {{firstName()}}<br>
last name : {{lastName()}}<br>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
name: {}
},
data() {
return {}
},
created: function () {
},
methods: {
firstName() {
return this.name.split(' ')[0]
},
lastName() {
return this.name.split(' ')[1]
},
},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
메소드를 이용해서 해결하는 방법이 있다.
하지만 계속 저렇게()를 보는것도 좀 그렇다.
2.data로 위임받아서 해결합시다.
<!--Person.vue-->
<template>
<div class="person">
first name : {{firstName}}<br>
last name : {{lastName}}<br>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
name: {}
},
data() {
return {
firstName: this.name.split(' ')[0],
lastName: this.name.split(' ')[1],
}
},
created: function () {
},
methods: {
},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
훨씬 깔끔해 진것 같지만 더더욱 치명적인 문제가 있다.
왜냐하면 props가 바뀐다고해서 자식의 data가 바뀌지 않기 때문이다.
methods는 해당 데이터(props, data, computed)가 바뀌면 자동으로 바뀌게 된다.
(이 때 바뀌는 원리는 비효율적이게 돌아간다. 이유는 다음 포스팅에 언급하겠다.)
따라서 이런 문제를 해결?
하기 위해서라기보단 더 정확히 말하면 "이런 문제도 해결할 수 있는" watch라는 녀석이 등장하게 된 것이다.
watch - "난 감시하는 녀석"
<!--Person.vue-->
<template>
<div class="person">
first name : {{firstName}}<br>
last name : {{lastName}}<br>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
name: {}
},
watch: {
name() {
this.firstName = this.name.split(' ')[0];
this.lastName = this.name.split(' ')[1];
}
},
data() {
return {
firstName: this.name.split(' ')[0],
lastName: this.name.split(' ')[1],
}
},
created: function () {
},
methods: {},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
watch를 선언해주고 안에 변경할 변수의 이름을 적는다.
name() {
this.firstName = this.name.split(' ')[0];
this.lastName = this.name.split(' ')[1];
}
우리는 name의 변경을 감지할 것이므로 name을 적는다.
그러면 이제부터 name이라는 변수에 이벤트리스너가 달렸다고 생각하면된다.
이는 반드시 props일 필요는 없다. data나 computed도 감지하게 된다.
이제 동작하는걸 확인할 수 있다.
하지만 watch의 사용은 잘 권장되지 않는다.
디자인적인 관점에서, 디버깅적인 관점에서 사용할 경우 꽤 힘들어진다.
그래서 보통 watch는 이벤트 리스너로서 사용해야할 때 어쩔수 없이 쓰는 느낌이 강하다.
하지만 뭐... 다 핸들링할 자신있으면 사용해도 큰 무리는 없다는게 필자의 생각이다.
'Programming > JavaScript-Vue' 카테고리의 다른 글
[Vue-23]computed, 그리고 methods와의 차이(feat.watch) (0) | 2019.07.09 |
---|---|
[Vue-21]부모와 자식의 연결고리, Custom Event와 Event Bus (0) | 2019.07.02 |
[Vue-20]값의 동적 변경과 양방향바인딩, 그리고 v-model(실용편) (0) | 2019.06.28 |
[Vue-19]components와 props, 그 못다한 이야기 (0) | 2019.06.25 |
[Vue-18]vuex에서 helper를 사용하기(mapState, mapMutations, mapActions, mapGetters) (0) | 2019.06.19 |