본문 바로가기

데일리 공부 기록

vue2 - 사용자에게 input박스에 숫자를 콤마형식으로 보여주기

728x90

[목표]

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>