実は簡単なVueの双方向( two way )バインディング

1.子コンポーネントに value という名前の Props を作成する

必ず value という名前で作成しましょう

export default {
  props: {
    value: {
      type: String,
      required: true
    }
  }
}

2.子コンポーネントに computed を作成する

export default {
  computed: {
    inputValue: {
      get() {
        return this.value; 
      },
      set(value) {
        this.$emit('input', value); 
      }
    }
  } ,
}

$emitの書式は

$emit( '任意のイベント名' )

です。

3.子コンポーネントの input タグに v-modelを指定する

  <input type="text" v-model="inputValue" />

以上です。

4.呼び出し元の親コンポーネントの v-model を指定する

<my-component v-model="item.content.value"></my-component>

引用: https://b1tblog.com/2019/10/17/vue-vscode-addons/


補足

・補足1. v-model とは何か? (答: 次の書式のシンタックスシュガーです)

<input type="text" v-model="value">

  ↓ 同じ

<input type="text" :value="value" @input="e => value = e.target.value">
・「htmlタグのvalue」 に 変数 value の値をセットします。
・inputイベントに無名関数をセットしてその中で 変数valueに「htmlタグのvalue」をセットします。

なお、自動で付与されるイベントはhtmlタグによって異なります。

テキストと複数行テキストは、value プロパティと input イベントを使用します
チェックボックスとラジオボタンは、checked プロパティと change イベントを使用します
選択フィールドは、value プロパティと change イベントを使用します

・補足2. v-model="xxxxx" で指定する xxxxx はどこで宣言するのか?

data または computed(get() ,set() 両方指定)で宣言します。
同名で両方存在するときは data が使用されるので、同じ名前をつけるのはやめておきましょう(ややこしい)

data で変数 hoge を定義しておく

  data(){
    return {
      hoge: 1 ,
    }
  },

computed で変数 hoge を定義しておく
ゲッター(アクセサ)、セッター(ミューテータ) 、両方定義しておきましょう。

  computed: {
    hoge: {
      get() {
        return this.$store.state.myState.hoge;
      },
      set(value) {
        const key = 'hoge';
        this.$store.commit('myState',[key,value]);
      }
    }
  },

Vue3 での違いについて

https://v3.ja.vuejs.org/guide/migration/v-model.html#はじめに

2.x では、コンポーネントで v-model を使うことは、value プロパティを渡して input イベントを発火することと同じでした。

<ChildComponent v-model="pageTitle" />
<!-- これは下記の省略形です -->
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />
No.1959
05/06 09:44

edit