JavaScript와 HTML, CSS등에 대해서는 일체 다루지 않는다.
기초지식은 다른 강의를 참조하도록 하라.
참고:
v-model은 이미 해당 포스팅에서 한번 소개하였다.
해당포스팅에서 뭐라고 했었었냐면
그렇다 input의 value를 바꾸는게 현재 #app 컴포넌트의 name을 바꾸는 일과는 하등 상관이 없다.
우리가 바꾼것은 input 컴포넌트 내부의 name이다.
즉 쉽게말해서 app이라는것은 부모 컴포넌트이고 input은 자식 컴포넌트이다.
input박스에서 값을 바꾼것은 input의 값을 바꾼 것이다.
하지만 이를 app이라는 부모컴포넌트에 반영하려면 해당 포스팅에서 알려준 이벤트를 이용한것,
혹은 위에서 말했던 v-model을 사용하면된다.
이제 우리는 어느정도 vue를 알았으니까 v-model을 더 광범위로 적용해보도록하자.
component의 개념으로 양방향바인딩을 v-model을 사용해서 적용해보자.
예제를 바로 보도록하자.
<!--App.vue-->
<template>
<div id="app">
<Person v-model="name"></Person>
<div class="result">
name : {{name}}
</div>
</div>
</template>
<script>
import Person from "./components/Person";
export default {
name: 'App',
components: {Person},
data() {
return {
name: 'kukaro',
}
}
}
</script>
<style scoped>
.result {
padding: 5px;
background-color: yellowgreen;
}
</style>
App.vue는 부모 컴포넌트이다. 그리고 이녀석은 Person이라는 커스텀 컴포넌트를 자식으로 가지고 있다.
v-model로 연결되어있다. 이 행위에 대해서 우리는 어떻게 받아들여야하냐면
이 name이라는 녀석은 Person에서 바뀔 수 있고 또한 그 바뀐게 App이라는 부모에 적용도 될 수 있다는 것이다.
하지만 이렇게 했다고 끝은 아니고 자식도 몇가지 행위를 해줘야한다.
<!--Person.vue-->
<template>
<div class="person">
<label>
name : <input :value="value" @input="myChange"><br>
<!-- name : <input v-model="pvalue" @input="myChange"><br>-->
</label>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
value:{
},
},
data() {
return {
pvalue: this.value
}
},
created: function () {
},
methods: {
myChange($event) {
this.$emit('input', $event.target.value);
},
},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
자식의 경우에는 커스텀 이벤트를 발생시켜야한다.
일단 상세히보자.
props: {
value:{
},
},
props에서 value라는 녀석을 만들어준다.
이 value는 매우 아주아주 중요하다.
바로 부모에서 v-model로 던진 값은 value로 받는다.
그러므로 이는 사용하지 않아야한다.
this.$emit('input', $event.target.value);
부모에게 input이라는 이벤트를 위로 던져준다.
이 때 반드시 이벤트가 input이라는 이름으로 발생시켜준다.
왜냐하면 v-model은 input이라는 이벤트로 받기 때문이다.
name : <input :value="value" @input="myChange"><br>
<!--name : <input v-model="pvalue" @input="myChange"><br>-->
위의 방식이나 아래의 방식을 사용하면 되는데 v-model을 체이닝 해서 던지는건 조심해야한다.
그 이유는 체이닝 할 때 그냥 value를 체이닝 하면 안되는데 props른 readonly라는것을 망각해선 안된다.
그래서 여러분은 반드시 중간값으로 바꿔서 사용해야 한다.
이렇게 해주면 이제 v-model을 사용해서 값을 바인딩 할 수 있다.
부모가 자식을 바꾸고 자식이 부모를 바꾼다. 즉 양방향 바인딩이 가능한 것이다.
이제 테스트 해보자.
제대로 동작하는걸 확인할 수 있다.
선생님! v-model로 값을 multi로 바인딩 하는 방법은 없나요?
냥식이 잘 캐치를 했는데 지금 문법을 자세히 보면 알겠지만 값이 단지 name밖에 바인딩이 안된다.
하지만 여러분이 값을 둘 이상 바인딩 하고 싶다면 어떻게 해야할까?
바로 Object를 만들어서 토스하는 방식이다.
<!--App.vue-->
<template>
<div id="app">
<Person v-model="person"></Person>
<div class="result">
name : {{person.name}}<br>
age : {{person.age}}
</div>
</div>
</template>
<script>
import Person from "./components/Person";
export default {
name: 'App',
components: {Person},
data() {
return {
person: {
name: 'kukaro',
age: 26
},
}
}
}
</script>
<style scoped>
.result {
padding: 5px;
background-color: yellowgreen;
}
</style>
이렇게 person이라는 객체를 만들어서 값으로 던져준다.
<!--Person.vue-->
<template>
<div class="person">
<label>
name : <input name="name" :value="value.name" @input="myChange"><br>
age : <input name="age" :value="value.age" @input="myChange"><br>
</label>
</div>
</template>
<script>
export default {
name: 'Person',
props: {
value: {},
},
data() {
return {
pvalue: this.value
}
},
created: function () {
},
methods: {
myChange($event) {
if ($event.target.name === 'name') {
this.value.name = $event.target.value;
} else if ($event.target.name === 'age') {
this.value.age = $event.target.value;
}
this.$emit('input', this.value);
},
},
computed: {}
}
</script>
<style scoped>
.person {
padding: 10px;
background-color: skyblue;
}
</style>
그 다음 위처럼 코드를 수정해준다.
이제 한번 돌려보자.
제대로 동작하는걸 알 수 있다.
이렇게 v-model로 multi바인딩을 실현할 수 있다.
'Programming > JavaScript-Vue' 카테고리의 다른 글
[Vue-22]props 변경의 감시자, watch (0) | 2019.07.04 |
---|---|
[Vue-21]부모와 자식의 연결고리, Custom Event와 Event Bus (0) | 2019.07.02 |
[Vue-19]components와 props, 그 못다한 이야기 (0) | 2019.06.25 |
[Vue-18]vuex에서 helper를 사용하기(mapState, mapMutations, mapActions, mapGetters) (0) | 2019.06.19 |
[Vue-17]vuex 사용하기(actions로 비동기 통신) (0) | 2019.06.18 |