[목표]
1. 예를 들어 사용자가 금액을 입력한다.
금액은 천단위로 comma가 들어간다.
하지만 보여지는 것은 String으로 보여주지만
값을 다루는 부분은 Number 타입을 유지해야한다.
v-model을 사용하여 구현해보자
App.vue -> Number.vue 구조이다.
[App.vue]
<template>
<div>
<h2>Hello World!</h2>
<Number v-model="inputMoney"/>
</div>
</template>
<script>
import Number from './components/Number.vue';
export default {
components: {
Number,
},
data(){
return{
inputMoney: 1281934,
}
},
methods:{
receiveMoney(newValue){
this.inputMoney = newValue;
}
},
watch:{
inputMoney(value){
console.log(`App : ${value}`);
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
[Number.vue]
<template>
<div>
<h2>This is Number</h2>
<label for="money">Money</label>
<input type="text" v-model="사용자입력돈">
</div>
</template>
<script>
export default {
props: ['value'],
emits: ['emitMoney'],
data(){
return{
사용자입력돈: '',
}
},
methods: {
},
watch:{
value(value){
//정규식을 통해 임시검사를 한다.
let 임시검사 = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
console.log(`임시검사 : ${임시검사}`);
//검사한 값으로 사용자에게 보여주는 값으로 사용한다.
this.사용자입력돈 = 임시검사;
//
},
사용자입력돈(value){
//사용자가 입력한 값은 부모에게 다시 숫자로 바꿔서 보낸다
console.log(`검사전: ${value}`);
let 임시검사 = value.toString().replace(",","");
임시검사 = 임시검사.replace(",","");
임시검사 = 임시검사.replace(",","");
임시검사 = 임시검사.replace(",","");
임시검사 = 임시검사.replace(",","");
console.log(`검사후: ${임시검사}`);
임시검사 = parseInt(임시검사);
this.$emit('input', 임시검사);
}
},
mounted(){
this.사용자입력돈 = this.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");;
}
}
</script>
<style>
</style>
[ main.js]
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
해결한 뒤 얻은 점..
1. vue2에서는 v-model을 사용할 때
자식이 받을 때는 value 라는 이름으로 받는다.
2. vue2에서 자식-> 부모로 데이터 보낼 때에 emit를 사용한다.
그 때 emit 메소드 명을 따로 하지 않고 그냥 input으로 하면 넘어간다.
3. replace를 여러개 해놓은 걸 볼 수 있는데..
자꾸 하나씩 콤마를 안없애준다.
예를 들어 콤마가 두개면 replace 함수를 두번해줘야 기능이 정상적으로 작동한다.
4. props 데이터는 자식에서 부모 데이터를 사용하는 셈이니 수정이 불가하다.
따라서 따로 변수에 담아서 사용해야 한다.
게다가 타입까지 바꿔서 사용해야하니 복잡했다.
필요한 요구조건들을 순서대로 그림을 그렸다.
그림을 그리며 단계별로 필요한 기능이 어디에 있어야 하는지 체크했다.
체크한 뒤에 어떤 기술(watch? method? computed?)을 사용할 지에 대해 고민했다.
이렇게 하니 그나마 편하고 빠르게 해결이 가능했다.
추가로
내가 그렸던 그림을 토대로 기술을 접목시켰어도
중간 과정에 대한 결과물을 확인하며 수정해야했다.
그건 console.log 로 과정의 교차점마다 배치해놓았다.
그림을 그리며 해결 단계를 그리는 것, 중간 과정에 대한 결과물을 확인하는 것
이 두가지를 앞으로 잊지 않고 계속 실천해야겠다.
추가내용
<template>
<div>
<h2>This is Number</h2>
<label for="money">Money: </label>
<input ref="userInput" type="text" v-bind:value="computedInput" @input="emitData">
</div>
</template>
<script>
export default {
props: ['value'],
data(){
return{
사용자입력돈: '',
}
},
methods: {
sendData(data){
// console.log(`data ${data}`);
// console.log("sendData is Running...");
let 보낼값 = data.replace(",","");
for(let i in data){
if(data[i] == ',')
보낼값 = 보낼값.replace(",","");
}
// console.log(`보낼값: ${보낼값}`);
보낼값 = Object.is(parseInt(보낼값), NaN) ? 보낼값 = 0 : parseInt(보낼값);
this.$emit('input', 보낼값);
},
commaReg(val){
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
emitData(){
this.$refs.userInput.value = this.$refs.userInput.value.replace(/[^0-9]/g, '');
let temp = this.$refs.userInput.value;
this.sendData(temp);
},
},
computed:{
computedInput(){
// console.log("computedInput is Running...");
this.사용자입력돈 = this.commaReg(this.value);
return this.사용자입력돈;
}
},
mounted(){
// console.log("Mounted is Running...");
this.사용자입력돈 = this.commaReg(this.value);
}
}
</script>
<style>
</style>
'데일리 공부 기록' 카테고리의 다른 글
hands on vue3 - 재사용성이 높은 button component 만들어보기 (0) | 2023.03.14 |
---|---|
hands on vue3 - component를 이용해 누른 버튼에 따라 다른 화면 보여주기 (0) | 2023.03.14 |
hands on vue3 - 원하는 요소에 붙여넣는 teleport tag에 대한 연습 (0) | 2023.03.12 |
hands on vue3 - slot을 이용해 Modal Alert 띄우기(모달알럿) (0) | 2023.03.12 |
hands on vue3 - component 데이터를 삭제 방지를 위한 keep alive 태그를 알아보자 (0) | 2023.03.12 |