なぜVueでは、v-modelではなく入力イベントとしてハングルを受信する必要がありますか?


コードはコード砂箱で確認できます.

TL;DR

  • 韓国語を入力する場合は、v-modelではなく、入力イベントに直接状態を変更するHandlerをバインドしてください.
  • 😱 今日の質問


    今日の問題は、inputに韓国語を入力すると、inputイベントに応じてstateはすぐに変更されません.
    私が望んでいるのは、inputに値を入力すると、inputValueという反応型の値にすぐに反映されます.
    ただし、以下のようにハングルを入力し、focusが入力されている場合はinputValueに値が反映されません...
    そうなると確認できない~悲しい~いろんな問題が出てくる

    しかし、英語の状態はよく変わりました.
    <template>
      <div>
        <h1>v-model</h1>
        <input v-model="state.inputValue" />
        <div id="input-length">length : {{ state.inputLength }}</div>
      </div>
    </template>
    <script>
    import { computed, reactive } from "vue";
    export default {
      setup() {
        const state = reactive({
          inputValue: "",
          inputLength: computed(() => state.inputValue.length),
        });
        return {
          state,
        };
      },
    };
    </script>

    😀 ソリューション


    この問題の解決策は正式な書類に見つかった.IMEInput Method Editorの略語で、ハングルや漢字のようにパソコンのキーボードの文字よりも多くの文字を組み合わせて入力するシステムソフトです.
    For languages that require an IME (opens new window)(Chinese, Japanese, Korean etc.), you'll notice that v-model doesn't get updated during IME composition. If you want to respond to these updates as well, use an input event listener and value binding instead of using v-model.
    もし私が勝手に翻訳したら...
    中国語、日本語、韓国語などIMEが必要な言語では、v-modelはIMEグループの間、v-modelを更新しません.コンビネーション中に値の変化に応答する場合は、v-modelではなくvalueをinputイベントリスナーにバインドします.
    なるほど!
    inputイベントを直接検出し、event.target.valueをstateに保存するように変更します.すなわち、ハングル入力をstateに保存します.
    <template>
      <div>
        <h1>Input Event</h1>
        <input @input="onInput" />
        <div id="input-value">value : {{ state.inputValue }}</div>
        <div id="input-length">length : {{ state.inputLength }}</div>
      </div>
    </template>
    <script>
    import { computed, reactive } from "vue";
    export default {
      setup() {
        const state = reactive({
          inputValue: "",
          inputLength: computed(() => state.inputValue.length),
        });
    
        const onInput = ({ target: { value } }) => {
          state.inputValue = value;
        };
        return {
          state,
          onInput,
        };
      },
    };
    </script>
    <style scoped>
    #input-length,
    #input-value {
      font-weight: bold;
    }
    </style>