[Vue] v-model 양방향 바인딩

suhanLee·2022년 6월 20일
0

vue-basic

목록 보기
10/29

양방향 바인딩 직접구현 1 (v-model 사용x)

<template>
  <div>
    <div>
      {{ text }}
    </div>
    <div>
      <input type="text" :value="text" @input="inputHandler" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "양방향 바인딩",
    };
  },
  methods: {
    inputHandler(event) {
      this.text = event.target.value;
    },
  },
};
</script>

영문, 숫자, 한글 까지 잘 동작

양방향 바인딩 직접구현 2 (v-model 사용x)

<template>
  <div>
    <div>
      {{ text }}
    </div>
    <div>
      <input type="text" :value="text" @input="text = $event.target.value" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "양방향 바인딩",
    };
  },
  methods: {
    inputHandler(event) {
      this.text = event.target.value;
    },
  },
};
</script>

영문, 숫자, 한글 까지 잘 동작

양방향 바인딩 (v-model 사용o)

<template>
  <div>
    <div>
      {{ text }}
    </div>
    <div>
      <input type="text" v-model="text" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      text: "양방향 바인딩",
    };
  },
};
</script>


한글은 자음과 모음이 조합해서 사용하기 때문에
한글자씩 늦게 나옴

한글은 IME기능이 필요한 문자여서 그렇다
IME는 간단히 말해 문자의 조합을 도와주는 SW이다

Vue 공식문서에서는 IME가 필요한 언어들(한, 중, 일..등등)은 v-model 대신에 위의 예제 1, 2처럼 @input을 사용하길 권고 하고있음

v-model 관련 수식어

<template>
  <div>
    <div>
      {{ lazyText }} | {{ typeof lazyText }}
      <input type="text" v-model.lazy="lazyText" />
    </div>
    <div>
      {{ numberText }} | {{ typeof numberText }}
      <input type="text" v-model.number="numberText" />
    </div>
    <div>
      {{ trimText }} | {{ trimText.length }}
      <input type="text" v-model.lazy="trimText" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      lazyText: "기본",
      numberText: null,
      trimText: "        트림            ",
    };
  },
};
</script>

v-model.lazy : v-on:change 또는 @change대신 사용 가능
v-model.number : binding된 데이터는 문자이기 때문에 이 값을 숫자형으로 유지시켜줌
v-model.trim : 입력중 공백을 제거해 줌

v-model

input type="checkbox"

<template>
  <div>
    <input type="checkbox" v-model="check" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      check: false,
    };
  },
  watch: {
    check(newValue, oldValue) {
      console.log(`oldValue : ${oldValue}`);
      console.log(`newValue : ${newValue}`);
    },
  },
};
</script>




부모, 자식 컴포넌트 input 양방향 바인딩

부모 컴포넌트

<template>
  <div>
    {{ text }}
    <TextFieldSample @input="text = $event.target.value"></TextFieldSample>
    <TextFieldSample v-model="text"></TextFieldSample>
  </div>
</template>

<script>
import TextFieldSample from "@/components/TextFieldSample.vue";
export default {
  components: {
    TextFieldSample,
  },
  data() {
    return {
      text: "",
    };
  },
};
</script>

자식 컴포넌트

<template>
  <div>
    <input :value="value" @input="(value) => $emit('input', value)" />
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
      default: "",
    },
  },
};
</script>

0개의 댓글