Vue で親子コンポーネントの値を双方向バインドするために v-model を使用するときに発生する問題と解決策

Vue で親子コンポーネントの値を双方向バインドするために v-model を使用するときに発生する問題と解決策

シナリオ

今日、コンポーネントの双方向データバインディングにv-modelを使用しているときに奇妙な問題が発生しました。Web ページ自体は正常に実行されましたが、ブラウザに警告メッセージが表示され続けました。

[Vue 警告]: 親コンポーネントが再レンダリングされるたびに値が上書きされるため、プロパティを直接変更することは避けてください。代わりに、プロパティの値に基づいてデータまたは計算プロパティを使用してください。変更されるプロパティ: "value"

この警告はカスタムコンポーネントRxSelectによって発生します

Vue.component("RxSelect", {
 モデル: {
 プロパティ: "値",
 イベント: "変更",
 },
 小道具: {
 値: [数値、文字列],
 地図: 地図、
 },
 テンプレート: `
  <選択
   v-model="値"
   @change="$emit('change', 値)"
  >
   <オプション
   v-for="マップ内の[k,v]"
   :値="k"
   :key="k"
   >{{v}}</オプション>
  </選択>
  `、
});

使用しているコードは問題ないようです。

<メインid="アプリ">
 現在選択されている性別は: {{map.get(sex)}} です
 <div>
 <rx-select :map="マップ" v-model="性別" />
 </div>
</メイン>

JavaScript コード

新しいVue({
 el: "#app",
 データ: {
 マップ: 新しい Map().set(1, "機密").set(2, "男性").set(3, "女性"),
 性別: "",
 },
});

テスト後、プログラム自体は正常に実行され、親コンポーネントと子コンポーネント間の値の転送に問題はなく、双方向のデータバインディングは有効になりますが、ブラウザはエラーを報告し続けます。

解決してみる

方法を見つけた

  1. 双方向バインディングを必要とする変数の場合は、コンポーネントdataで変数innerValue宣言し、それをvalueに初期化します。
  2. この変数innerValueをバインドするには、 selectv-modelを使用します。
  3. valueの変化を監視し、親コンポーネントのvalue変更されたときにinnerValueの値を変更します。
  4. innerValueの変更を監視し、 this.$emit('change', val)を使用して、変更があった場合にvalueを更新する必要があることを親コンポーネントに伝えます。
Vue.component("RxSelect", {
 モデル: {
 プロパティ: "値",
 イベント: "変更",
 },
 小道具: {
 値: [数値、文字列],
 地図: 地図、
 },
 データ() {
 戻る {
  内部値: this.value、
 };
 },
 時計:
 値(val) {
  this.innerValue = val;
 },
 内部値(val) {
  this.$emit("change", val);
 },
 },
 テンプレート: `
 <v-model="innerValue" を選択">
 <オプション
  v-for="マップ内の[k,v]"
  :値="k"
  :key="k"
 >{{v}}</オプション>
 </選択>
 `、
});

使用コードはまったく同じですが、コンポーネントRxSelectのコードははるかに長くなります。 。 。

解決する

よりエレガントな方法は、 computedプロパティとそのget/set使用することですが、追加されるコードの量は許容範囲内です。

Vue.component("RxSelect", {
 モデル: {
 プロパティ: "値",
 イベント: "変更"、
 },
 小道具: {
 値: [数値、文字列],
 地図: 地図、
 },
 計算: {
 内部値: {
  得る() {
  this.value を返します。
  },
  設定(値) {
  this.$emit("change", val);
  },
 },
 },
 テンプレート: `
 <v-model="innerValue" を選択">
 <オプション
  v-for="マップ内の[k,v]"
  :値="k"
  :key="k"
 >{{v}}</オプション>
 </選択>
 `、
});

上記は、Vue が v-model を使用して親コンポーネントと子コンポーネントの値を双方向バインドするときに発生する問題と解決策の詳細です。Vue が v-model を使用して親コンポーネントと子コンポーネントの値を双方向バインドすることの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • v-model 双方向バインディングデータを実装する vue カスタム コンポーネントのサンプル コード
  • vue3 コンポーネントでの v-model の使用と詳細な説明
  • Vue の v-model ディレクティブと .sync 修飾子の違いの詳細な説明
  • Vue の双方向イベントバインディング v-model の原理についての簡単な説明
  • Vueはv-modelを使用してel-paginationコンポーネントのプロセス全体をカプセル化します。
  • Vue における v-model を使用したクロスコンポーネントバインディングの基本的な実装方法
  • Vue フォーム入力ボックスがフォーカスおよびぼかしイベントをサポートしていない問題の解決策
  • カスタムイベントを使用した Vue のフォーム入力コンポーネントの詳細な使用方法 [日付コンポーネントと通貨コンポーネント]
  • Vue フォーム入力バインディングのサンプルコード
  • Vue フォームの入力フォーマットの中国語入力方法の異常
  • Vue フォーム入力バインディング v-model

<<:  MySQLはトリガーを使用してデータベース内のテーブルの行制限を解決します。詳細な説明と例

>>:  Nginx 仮想ホストを構成する 3 つの方法 (ポートベース) の詳細な説明

推薦する

CSSを使用して複数の画像を中央に水平に表示する方法

まず実装手順について説明します。最終結果 2. コードの実装HTML部分 <div class...

MySQL 8.0.18はデータベースにユーザーを追加し、権限を付与します

1. データベースにログインするには、rootユーザーを使用することをお勧めします。 mysql -...

SQL でテーブルにフィールドとコメントを追加する方法

1. フィールドを追加します。 alter table テーブル名 ADD フィールド名 タイプ;例...

JavaScript配列の一般的なメソッドの概要

目次1. はじめに2. フィルター() 3. マップ() 4. ソート() 5. 減らす() 6. ...

1行のコードでLinuxのプロセスを隠す方法を学ぶ

友人たちはいつも、Linux のプロセスを隠す方法を私に尋ねます。私は、どの程度隠したいのか、カーネ...

Linux で Golang をインストールする方法

Go は、シンプルで信頼性が高く、効率的なソフトウェアを簡単に構築できるオープンソース プログラミン...

Vueはシンプルな虫眼鏡効果を実装します

この記事では、参考までに、簡単な虫眼鏡効果を実現するためのVueの具体的なコードを紹介します。具体的...

MySQL の group by と having の詳細な説明

GROUP BY 構文を使用すると、指定されたデータ列の各メンバーに従ってクエリ結果をグループ化して...

Vue2.0/3.0双方向データバインディングの実装原理の詳細説明

Vue2.0/3.0双方向データバインディングの実装原理双方向データバインディングとは、データの変更...

MySQLの誤操作後にbinlog2sqlを使用して素早くロールバックする方法の詳細な説明

序文日常の仕事や勉強では、データベースを操作するときに「不注意」によるミスを犯すことは避けられません...

Vue 監視属性のグラフィック例の詳細な説明

目次リスナープロパティとは何ですか?リスニングプロパティと計算プロパティの違いは何ですか?監視プロパ...

Dockerを使用してプライベートGitLabを構築する2つの方法

最初の方法: docker インストール1. オープンソース版のイメージを取得する2. 対応するデー...

YUMを使用してdockerをインストールする方法

次の図に示すように: Centos 7.0以上であれば問題ありません。現在のシステム カーネル バー...

Windows Server 2016 に Docker をインストールするプロセスと発生した問題

前提条件Windows Server でコンテナーを実行するには、Windows Server (半...