子コンポーネントを通じて親コンポーネントのプロパティを変更するための Vue のさまざまな実装方法

子コンポーネントを通じて親コンポーネントのプロパティを変更するための Vue のさまざまな実装方法

序文

実際の業務プロジェクト開発では、親コンポーネントが最初に子コンポーネントに値を渡し、その後子コンポーネントがシーンをレンダリングして表示するというシナリオがよくあります。以下に、現在の業務で遭遇して使用したいくつかの方法をまとめました。実装方法やアイデアの参考になります。誤解や他の方法がある場合は、コメント欄にメッセージを残して指導してください〜

一般的な方法

一方向の prop 転送ルールに従うことをお勧めします。基本データ型と参照データ型の両方が許容されます。

1. 親コンポーネントを介して子コンポーネントの発行イベントをリッスンしてpropを変更します。

原理:

  • 子コンポーネントの input タグの value 属性をバインドし、prop に値を割り当てます。v-model の代わりに value が使用されるため、入力値を変更しても prop には影響しません。
  • 次に、入力イベントを入力にバインドします。各入力は入力イベントをトリガーします。イベントでは、this.$emit('親がリッスンするイベント名'、変更された値) を使用して値を上方に渡します。
  • 親コンポーネントは、 on を使用して、子コンポーネントによってトリガーされたばかりの emitting イベントをリッスンし、イベントによって渡された値を親コンポーネントのデータに更新します。
  • 親コンポーネントのデータの値が更新されると、その値は prop を介して子コンポーネントに渡されるため、子コンポーネントも prop 値を同期的に更新し、ビュー レイヤーをレンダリングします。

放出する

親コンポーネントのコードは次のとおりです。

<テンプレート>
  <div style="background-color: skyblue;">
    <h3>子コンポーネントが親コンポーネントを介してイベントを発行するのをリッスンしてプロパティを変更します</h3>
    <div>親オブジェクト:{{ obj }}</div>
    <div>親メッセージ:{{ メッセージ }}</div>
    <!-- 親コンポーネントが子コンポーネントを呼び出すと、子コンポーネントによってトリガーされた放出イベントを on 経由でリッスンして値を受け取り、ユーザーを更新します -->
    <emitChild
      :obj="obj"
      :msg="メッセージ"
      @update-obj="updateObj"
      @update-msg="更新メッセージ"
    />
  </div>
</テンプレート>

<スクリプト>
'./components/emitChild' から emittingChild をインポートします。

エクスポートデフォルト{
  名前: 'emitUpdate',
  コンポーネント:
    子を放出する
  },
  データ () {
    戻る {
      オブジェクト: {
        名前: 'zhangsan'、
        年齢: 18
      },
      メッセージ: 'こんにちは'
    }
  },
  メソッド: {
    // 子コンポーネントによってトリガーされたイベントをリッスンし、データ内のオブジェクトを更新します
    updateObj (キー、newVal) {
      this.obj[キー] = newVal
    },
    // 子コンポーネントによってトリガーされたイベントをリッスンし、データ内のメッセージを更新します
    更新メッセージ (新しい値) {
      this.msg = 新しい値
    }
  }
}
</スクリプト>

サブコンポーネントコードは次のとおりです。

<テンプレート>
  <div style="background-color: pink;">
    <div>
      <span>名前を変更:</span>
      <!-- ここで、バインディング値は value です。これは、入力が主にプロパティ データを表示するために使用され、実際の変更はサブコンポーネント内にないためです。サブコンポーネントは変更トリガー ソースとしてのみ使用されます -->
      <!-- 入力イベントをトリガー ソースのエントリ ポイントとしてバインドします -->
      <input type="text" :value="obj.name" @input="updateObj($event, 'name')">
    </div>
    <div>
      <span>年齢を変更:</span>
      <input type="text" :value="obj.age" @input="updateObj($event, 'age')">
    </div>
    <div>
      <span>メッセージを変更:</span>
      <input type="text" :value="msg" @input="updateMsg($event.target.value)">
    </div>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'emitUpdateChild',
  小道具: {
    オブジェクト: {
      タイプ: オブジェクト、
      デフォルト: () => {}
    },
    メッセージ: {
      タイプ: 文字列、
      デフォルト: ''
    }
  },
  メソッド: {
    // 親コンポーネントに obj を更新するよう通知する
    updateObj ($event, キー) {
      // 入力値と、更新する必要がある obj 内の対応する属性を受け取り、それを親コンポーネントに返します // 親コンポーネントは、子コンポーネントが更新する必要がある obj 内の属性値を知ることができます this.$emit('update-obj', key, $event.target.value)
    },
    // 親コンポーネントにメッセージの更新を通知する
    更新メッセージ (新しい値) {
      this.$emit('update-msg', newVal)
    }
  }
}
</スクリプト>

2. 親コンポーネントの同期修飾子と子コンポーネントの発行イベントを介してプロパティを変更する

原理:

  • 子コンポーネントの input タグの value 属性をバインドし、prop に値を割り当てます。v-model の代わりに value が使用されるため、入力値を変更しても prop には影響しません。
  • 次に、入力イベントを入力にバインドします。各入力は入力イベントをトリガーします。イベントでは、this.$emit('親がリッスンするイベント名'、変更された値) を使用して値を上方に渡します。
  • 親コンポーネントが子コンポーネントを呼び出してプロパティを渡す場合、プロパティの後に .sync を追加して、イベントによって渡された値を親コンポーネントのデータに更新します。これは、sync が実際にはコード @Listener child triggered event name = "property name in parent data = value passing by emitting (ie $event)" を実行することと同じであるためです。
  • 親コンポーネントのデータの値が更新されると、その値は prop を介して子コンポーネントに渡されるため、子コンポーネントも prop 値を同期的に更新し、ビュー レイヤーをレンダリングします。

同期

親コンポーネントのコードは次のとおりです。

<テンプレート>
  <div style="background-color: skyblue;">
    <h3>親コンポーネントの同期修飾子と子コンポーネントの発行イベントを介してプロパティを変更する</h3>
    <div>親オブジェクト:{{ obj }}</div>
    <div>親メッセージ:{{ メッセージ }}</div>
    <!-- 親コンポーネントが子コンポーネントを呼び出してプロパティを渡す場合は、プロパティの後に .sync を追加するだけです -->
    <syncChild:obj.sync="obj":msg.sync="msg" />
    <!--
      同期は実際には、@listener トリガー イベント名 = "親データのプロパティ名 = エミットによって渡された値 (つまり $event)" を実行することと同じです。
      このコード -->
    <!-- 効果は次のコードと同等なので、親コンポーネントのメソッドでデータを変更するメソッドを定義する必要はありません-->
    <!--
      <同期子
        :obj="obj"
        :msg="メッセージ"
        @update-obj="obj = $event"
        @update-msg="メッセージ = $イベント"
      />
    -->
  </div>
</テンプレート>

<スクリプト>
'./components/syncChild' から syncChild をインポートします。

エクスポートデフォルト{
  名前: 'syncUpdate',
  コンポーネント:
    同期子
  },
  データ () {
    戻る {
      オブジェクト: {
        名前: 'zhangsan'、
        年齢: 18
      },
      メッセージ: 'こんにちは'
    }
  }
}
</スクリプト>

サブコンポーネントコードは次のとおりです。

<テンプレート>
  <div style="background-color: pink;">
    <div>
      <span>名前を変更:</span>
      <!-- ここで、バインディング値は value です。これは、入力が主にプロパティ データを表示するために使用され、実際の変更はサブコンポーネント内にないためです。サブコンポーネントは変更トリガー ソースとしてのみ使用されます -->
      <!-- 入力イベントをトリガー ソースのエントリ ポイントとしてバインドします -->
      <input type="text" :value="childObj.name" @input="updateObj($event, 'name')">
    </div>
    <div>
      <span>年齢を変更:</span>
      <input type="text" :value="childObj.age" @input="updateObj($event, 'age')">
    </div>
    <div>
      <span>メッセージを変更:</span>
      <input type="text" :value="msg" @input="updateMsg($event.target.value)">
    </div>
  </div>
</テンプレート>

<スクリプト>
// ここでは lodash ツールライブラリの cloneDeep ディープコピーメソッドを紹介します // 公式ドキュメントアドレス https://www.lodashjs.com/
'lodash' から { cloneDeep } をインポートします

エクスポートデフォルト{
  名前: 'emitUpdateChild',
  小道具: {
    オブジェクト: {
      タイプ: オブジェクト、
      デフォルト: () => {}
    },
    メッセージ: {
      タイプ: 文字列、
      デフォルト: ''
    }
  },
  データ () {
    戻る {
      // ここでは、prop の obj がディープ コピーによってコピーされます。主な目的は次の通りです。
      // 1. 異なるメモリアドレスを使用して 2 つのオブジェクト (参照型) を区別します // 2. 子コンポーネントのレンダリング/変更/返却を容易にするために、オブジェクト内のすべての値を保持します childObj: cloneDeep(this.obj)
    }
  },
  メソッド: {
    // 親コンポーネントに obj を更新するよう通知する
    updateObj ($event, キー) {
      // 入力値と、更新する必要がある childObj 内の対応する属性を受け取ります // 次に、childOBj を更新して親コンポーネントに渡します // 親コンポーネントは、取得した childObj をデータの obj に直接更新できます this.childObj[key] = $event.target.value
      this.$emit('update:obj', this.childObj)
    },
    // 親コンポーネントにメッセージの更新を通知する
    更新メッセージ (新しい値) {
      this.$emit('update:msg', newVal)
    }
  }
}
</スクリプト>

ヒント

これは主に参照データ型を対象とし、Vue のプロパティ検出メカニズムをバイパスします。プロジェクトの仕様でこの記述が許可されているかどうかによって異なります。

3. データを通じてプロパティを変更する

前提条件: 参照データ型のみ実装可能

原理:

  • 親コンポーネントから渡された prop を子コンポーネントの data に直接代入します。このとき、prop と data の両側の変数は同じメモリ アドレスを指しているため、データを変更することは prop を変更することと同等になります。
  • Vue2 では props を直接変更することはできませんが、今回は props ではなくデータを変更しているため、Vue はエラーをスローしません。これは、props の変更を許可しない Vue の検出メカニズムをバイパスすることと同じです。

データ

親コンポーネントのコードは次のとおりです。

<テンプレート>
  <div style="background-color: skyblue;">
    <h3>prop をデータに割り当てて変更する</h3>
    <div>親オブジェクト:{{ obj }}</div>
    <div>親メッセージ:{{ メッセージ }}</div>
    <dataChild :obj="obj" :msg.sync="msg" />
  </div>
</テンプレート>

<スクリプト>
'./components/dataChild' から dataChild をインポートします。

エクスポートデフォルト{
  名前: 'dataUpdate',
  コンポーネント:
    データ子
  },
  データ () {
    戻る {
      オブジェクト: {
        名前: 'zhangsan'、
        年齢: 18
      },
      メッセージ: 'こんにちは'
    }
  }
}
</スクリプト>

サブコンポーネントコードは次のとおりです。

<テンプレート>
  <div style="background-color: pink;">
    <div>
      <span>名前を変更:</span>
      <!-- ここでは、prop をデータに直接割り当てているため、v-model の双方向バインディングを直接使用してデータを変更できます -->
      <input type="text" v-model="dataObj.name">
    </div>
    <div>
      <span>年齢を変更:</span>
      <input type="text" v-model="dataObj.age">
    </div>
    <div>
      <span>メッセージを変更:</span>
      <!-- ウォッチ リスナーを通じて実装できる基本データ型を変更する別の方法を示します -->
      <input type="text" v-model="dataMsg">
    </div>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'dataChild',
  小道具: {
    オブジェクト: {
      タイプ: オブジェクト、
      デフォルト: () => {}
    },
    メッセージ: {
      タイプ: 文字列、
      デフォルト: ''
    }
  },
  データ () {
    戻る {
      // 参照データ型が直接割り当てられると、それは浅いコピーとなり、メモリアドレスのみがコピーされ、一方を変更するともう一方に反映されます。dataObj: this.obj、
      // 基本データ型を直接割り当てると、値がコピーされ、一方を変更してももう一方には影響しません。dataMsg: this.msg
    }
  },
  時計:
    // ここでは、データからコピーされた dataMsg をリッスンし、変更されたら、emit を実行して親コンポーネントに dataMsg (newVal) を更新するように通知します。{
      this.$emit('update:msg', newVal)
    }
  }
}
</スクリプト>

4. 計算プロパティを通じてpropを変更する

前提条件: 参照データ型のみ実装可能

原理:

  • 子コンポーネントでは、親コンポーネントから渡された prop が、計算プロパティ computed を通じて直接リッスンされます。このとき、計算プロパティ computed と prop の両側の変数は同じメモリ アドレスを指しているため、計算プロパティ computed を変更することは prop を変更することと同じです。
  • Vue2 では props を直接変更することはできませんが、今回は prop ではなく計算プロパティ computed を変更しているため、Vue はエラーをスローしません。これは、props の変更を許可しない Vue の検出メカニズムをバイパスすることと同じです。

計算された

親コンポーネントのコードは次のとおりです。

<テンプレート>
  <div style="background-color: skyblue;">
    <h3>計算プロパティの監視を通じてプロパティを変更する</h3>
    <div>親オブジェクト:{{ obj }}</div>
    <div>親メッセージ:{{ メッセージ }}</div>
    <computedChild :obj="obj" :msg.sync="msg" />
  </div>
</テンプレート>

<スクリプト>
'./components/computedChild' から computedChild をインポートします。

エクスポートデフォルト{
  名前: 'computedUpdate',
  コンポーネント:
    計算された子
  },
  データ () {
    戻る {
      オブジェクト: {
        名前: 'zhangsan'、
        年齢: 18
      },
      メッセージ: 'こんにちは'
    }
  }
}
</スクリプト>

サブコンポーネントコードは次のとおりです。

<テンプレート>
  <div style="background-color: pink;">
    <div>
      <span>名前を変更:</span>
      <!-- ここでは、算出プロパティを通じて prop を直接リッスンしているので、v-model の双方向バインディングを直接使用してデータを変更できます -->
      <input type="text" v-model="computedObj.name">
    </div>
    <div>
      <span>年齢を変更:</span>
      <input type="text" v-model="computedObj.age">
    </div>
    <div>
      <span>メッセージを変更:</span>
      <!-- 基本データ型を変更する別の方法は、計算プロパティのセッターを通じて実現できます -->
      <input type="text" v-model="computedMsg">
    </div>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'computedChild',
  小道具: {
    オブジェクト: {
      タイプ: オブジェクト、
      デフォルト: () => {}
    },
    メッセージ: {
      タイプ: 文字列、
      デフォルト: ''
    }
  },
  計算: {
    計算されたオブジェクト() {
      // ここでは、参照データ型objが直接返されます。この時点で、computedObjはobjと同等です。
      // これは浅いコピーなので、メモリアドレスのみがコピーされ、一方を変更するともう一方に反映されます。 return this.obj
    },
    計算されたメッセージ: {
      得る () {
        // プロパティが更新されるたびに、計算プロパティのゲッターメソッドがトリガーされ、最新の値が取得されます // 基本データ型を直接返す場合、値がコピーされ、一方を変更してももう一方には影響しません。 return this.msg
      },
      設定(新しい値) {
        // ここでは、計算プロパティのセッターメソッドを使用して、値が変更されたときにエミットをトリガーし、親コンポーネントに値を更新するように通知します。this.$emit('update:msg', newVal)
      }
    }
  }
}
</スクリプト>

これで、子コンポーネントを介して親コンポーネントのプロパティを変更する Vue の実装方法に関するこの記事は終了です。親コンポーネントのプロパティを変更する Vue 子コンポーネントに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vueの子コンポーネントが親コンポーネントのメソッドを呼び出す場合の詳細な説明
  • Vue 親コンポーネントが子コンポーネント関数の実装を呼び出す
  • Vue で親コンポーネントから子コンポーネントにデータを渡すいくつかの方法
  • Vue の親コンポーネントのボタンをクリックして子コンポーネントをトリガーするイベントの詳細な説明
  • vueの子コンポーネントと親コンポーネント間で値を渡す例
  • Vue親コンポーネントは子コンポーネントのライフサイクルを監視します
  • Vue親コンポーネントはどのようにして子コンポーネントの変数を取得するのか
  • Vueの子コンポーネントと親コンポーネントの詳細な分析

<<:  MySQL における悲観的ロックと楽観的ロック

>>:  MySQL の自動増分 ID (主キー) が不足した場合の解決策

推薦する

Mysqlリモート接続構成を実装する2つの方法

Mysqlリモート接続構成を実装する2つの方法会社で働いていると、誰かのコンピュータに保存されている...

nginx-naxsi ホワイトリストルールの詳細な説明

ホワイトリストルールの構文:基本ルール wl:ID [否定] [mz:[$URL:target_ur...

ネイティブ JS でスネーク ゲームを書く

この記事では、参考までに、JSでスネークゲームを書くための具体的なコードを紹介します。具体的な内容は...

npmとcnpmを混在させる際の落とし穴の詳細な説明

目次原因理由NPM の紹介: CNPM の紹介:より良い方法方法の改善npm と cnpm を一緒に...

JavaScriptはフォームデータの非同期取得を実装します

この記事では、フォームデータの非同期取得を実現するためのJavaScriptの具体的なコードを例とし...

Dockerコンテナのエクスポートとインポートの例

目次DockerコンテナのエクスポートDockerコンテナのインポ​​ートこの記事では主に、コンテナ...

HTMLでカメラを読み込む方法

効果図: 全体的な効果: ビデオ読み込み中: 写真:ステップ1: HTML要素を作成するまず、HTM...

Centos7 DockerでNginxファイルを変更するプロセスの詳細な説明

1. docker に nginx をインストールします。 docker に Nginx をインスト...

CSS フォントの新しい使い方: カラーフォントの実装

デザイナーが特別なイベントのタイトルフォントとして以下のフォントを使用したい場合はどうすればよいでし...

MySQL のインデックスと制約の例文

外部キーテーブルの主キーがどのテーブルの外部キーであるかを照会する 選択 テーブル名、 列名、 制約...

MySQLは1億のテストデータを素早く挿入します

目次1. テーブルを作成する1.1 テストテーブルt_userを作成する1.2 一時テーブルの作成2...

HTML テーブルタグと関連する改行の問題の詳細な分析

テーブルとは何ですか?テーブルは、データのキャリアである HTML テーブルです。以下は比較的標準的...

MySQLで日付を比較する方法の詳細な説明

データ型が datetime であるフィールド add_time を持つテーブル product が...

Centos7 サーバーで jar パッケージ プロジェクトを開始する最良の方法

序文Linux 上で jar パッケージを実行する方法は誰もが知っています。なぜ別々に話したいのでし...

JSオブジェクトの走査順序の詳細な説明

JavaScript ではオブジェクトを走査する順序は固定されていないと聞いたことがある人もいるかも...