페이지 목차
INPUT 태그 한글 바인딩에 관하여
- 안녕하세요. VUE를 통해 개발 중, 이상한? 문제점을 맞닥뜨렸습니다. 문제는 바로 input tag 입력 시 한글 바인딩에 관해서입니다.
<p class="subTxt">
{{$t('hostingReg.reg2.title') +' ' + '('+20+'/'+hosting.hostingTitle.length +')'}}
</p>
<input class="certi phone" :placeholder="$t('hostingReg.reg2.titleEx')" v-model="hosting.hostingTitle" :maxlength="20"/>
- 위에 이미지에서 보이는 것과 같이 영어나 숫자 입력 시, length가 제대로 바인딩 되지만 한글 입력 시, 두 번째 글자부터 length가 바인딩 되는 것이 보였습니다. 그래서 텍스트가 어떻게 바인딩 되는지 아래와 같이 테스트를 진행해 보았습니다.
<p class="subTxt">
{{$t('hostingReg.reg2.title') +' ' + '('+20+'/'+hosting.hostingTitle.length +')'}}
</p>
<input class="certi phone" :placeholder="$t('hostingReg.reg2.titleEx')" v-model="hosting.hostingTitle" :maxlength="20"/>
- 한글의 경우 즉시 바인딩이 되지 않고 문자가 완성된 후에 바인딩이 되는 것을 확인하였습니다. 왜 그럴까요?? 해당 정답은 ?VUE 공식 사이트에서 찾을 수 있었습니다.
For languages that require an IME (Chinese, Japanese, Korean, etc.), you’ll notice that v-model doesn’t get updated during IME composition. If you want to cater to these updates as well, use the input event instead.
IME가 필요한 언어 (중국어, 일본어, 한국어 등)의 경우 IME 작성 중에 v-model이 업데이트되지 않음을 알 수 있습니다. 이러한 업데이트에도 적용하려면 @input 이벤트를 대신 사용하십시오.
- 아하 IME(‘IME는 한글, 한자처럼 컴퓨터 자판에 있는 글쇠보다 수가 더 많은 문자를 계산하거나 조합하여 입력해 주는 시스템 소프트웨어이다.’) 가 필요한 언어의 경우 v-model이 업데이트되지 않는 것을 할 수 있었습니다. 그리고 해결방법도요. @input 이벤트를 사용하라~ 바로 이부분입니다. 그럼 해당 부분을 통해 다음과 같이 테스트를 진행하였습니다.
<p class="subTxt">
{{$t('hostingReg.reg2.title') +' ' + '('+20+'/'+hosting.hostingTitle.length +')'}}
</p>
<input class="certi phone" :placeholder="$t('hostingReg.reg2.titleEx')" :value="hosting.hostingTitle" @input="inputhostingTitle($event)" :maxlength="20"/>
methods: {
inputhostingTitle(event) {
this.hosting.hostingTitle = event.target.value;
},
}
- 오 잘되는 것을 확인하였습니다. 그러나 한가지의 문제점이 더 있었습니다. 매번 저렇게 @input 이벤트를 만들어서 바인딩해주면 귀찮지 않을까?? 그러한 생각을 통해 저 @input 부분을 컴포넌트로 만들면 되겠다는 생각에 도달하였습니다. 그리하여 다음과 같이 작업을 진행하였습니다.
<p class="subTxt">
{{$t('hostingReg.reg2.title') +' ' + '('+20+'/'+hosting.hostingTitle.length +')'}}
</p>
<CustomInput :pclass="'certi phone'" :placeholder="$t('hostingReg.reg2.titleEx')" v-model="hosting.hostingTitle" :maxlength="20" />
<template>
<input
:style="{ 'color': redColorFlag!==null && redColorFlag !== undefined?redColorFlag?'red':'':''}"
:type="type!==null && type !== undefined?type:'text'" :class="pclass" :placeholder="placeholder" :value="value" @input="inputChange" @keyup.enter="enterMethod()">
</template>
<script>
export default {
name: 'input',
props:['pclass','placeholder','value','enterMethod','changeTxt','type','maxlength','redColorFlag'],
data() {
return{
}
},
mounted(){
},
methods: {
inputChange(event){
if(this.maxlength!==null && this.maxlength !==undefined){
if(event.target.value.length > Number(this.maxlength)) {
event.target.value = event.target.value.slice(0, Number(this.maxlength));
return
}
}
this.$emit('input', event.target.value);
if(this.changeTxt!==null && this.changeTxt!==undefined){
this.changeTxt()
}
}
}
}
</script>
- 컴포넌트를 하나 생성 후 필요정보들(class,placeholder,value,maxlength 등) 을 받아서 emit을 통해 리턴해주는 방식으로 구성하였습니다. 위 컴포넌트를 통해 모든 input에 심플하게 적용할 수 있게 되었습니다.
VUE 사용 시 components를 통해 깔끔하게 사용할 수 있다.!!!
- references:
- Written by: 이재봉 (jblee6110@gmail.com)
- reporting date: 2021-05-06