Vue.$set の失敗の落とし穴の発見と解決

Vue.$set の失敗の落とし穴の発見と解決

偶然、プロジェクト内でVue.$setが無効であることがわかりました

データ フィルタリングを追加する必要があります。左側はコントロールの選択、中央は条件、右側は値です。

コントロールに応じて異なる値オプションコントロールがレンダリングされるため

    <el-form インライン>
      <el-form-item スタイル="margin-bottom: 20px;">
        <el-select v-model="data[props.prop]" @change="data[props.value] = ''">
          <el-オプション
            v-for="コントロール内の項目"
            :key="アイテムID"
            :value="アイテムID"
            :label="item.label">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item スタイル="margin-bottom: 20px;">
        <el-select v-model="データ[props.type]">
          <el-オプション
            v-for="条件内のアイテム"
            :key="アイテムコード"
            :value="アイテムコード"
            :label="アイテム名"
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item スタイル="margin-bottom: 20px;">
        <FormControl v-if="control" :control="control" :value="data[props.value]" @input="onValueChange" ></FormControl>
        <el-input v-else :value="data[props.value]" @input="onValueChange"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-plus" @click="add"></el-button>
      </el-form-item>
    </el-form>
{
  小道具:{
    小道具: {
      タイプ: オブジェクト、
      デフォルト: () => ({
        プロップ: 'プロップ',
        値: '値',
        タイプ: 'タイプ'
      })
    }
  },
  データ(){
    戻る {
      データ:{
        
      }
    }
  },
  方法:{
    onValueChange(val){
      this.$set(this.data, this.props.value, val)
    }
  }
  //...
}

コードスニペット

コントロールIDが不確定なため、すべてのデータをキーであらかじめプリセットしておくことはできず、当然応答は不可能です。そこで、onValueChangeでthis.$setを使用して動的にデータを追加し、応答を実現しています。

再現すると、値入力ボックスのデータがリアルタイムで応答できないことがわかります

$set を使ったのですが反応しませんでした。調べてみると、コントロールを切り替えた後に値が反応しないことがわかりました。ただし、切り替える前に何か入力してから切り替えれば問題はありません。

さらに調査した結果、

<el-select v-model="data[props.prop]" @change="data[props.value] = ''">

@changeイベントを削除すると問題は解決します

問題は、data[props.value] = '' の場合に発生します。

Vueのソースコードを確認してください

//vue/src/core/observer/index.js ソースコードスニペット/**
 * オブジェクトにプロパティを設定します。新しいプロパティを追加し、
 * プロパティが
 * すでに存在します。
 */
エクスポート関数セット (ターゲット: 配列<any> | オブジェクト、キー: any、値: any): any {
  (process.env.NODE_ENV !== 'production' && の場合
    (isUndef(ターゲット) || isPrimitive(ターゲット))
  ){
    警告(`未定義、null、またはプリミティブ値にリアクティブ プロパティを設定できません: ${(target: any)}`)
  }
  Array.isArray(ターゲット) && isValidArrayIndex(キー) の場合 {
    ターゲットの長さ = Math.max(ターゲットの長さ、キー)
    ターゲット.splice(キー、1、値)
    戻り値
  }
  if (ターゲットのキー && !(Object.prototype のキー)) {
    ターゲット[キー] = 値
    戻り値
  }
  const ob = (ターゲット: 任意).__ob__
  target._isVue の場合、ob と ob.vmCount は次のように記述します。
    process.env.NODE_ENV !== 'production' && 警告(
      'Vue インスタンスまたはそのルート $data にリアクティブ プロパティを追加しないでください ' +
      「実行時 - データ オプションで事前に宣言します。」
    )
    戻り値
  }
  もし (!ob) {
    ターゲット[キー] = 値
    戻り値
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  戻り値
}

defineReactive の前に、オブジェクト内にキーが存在するかどうかが判断されていることがわかります。存在する場合はスキップされます。

問題はここにあります。Vue.$set ドキュメントを何度も読みましたが、$set では既存のキーに監視オブジェクトを追加できないことに気づきませんでした。

data[props.value] = ''を削除し、onValueChange('')に変更すると問題が完全に解決されます

要約する

Vue.$set の前に、オブジェクトにキーが存在してはいけません。そうでない場合は、値のみが更新され、キーの応答監視は追加されません。

上記は私の個人的な経験です。参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue での this.$set の動的データバインディングのケーススタディ
  • Vue - 計算プロパティ「****」が割り当てられましたが、セッターがありませんというエラーの解決。
  • vue3.0 でのセットアップの使用 (2 つの使用方法)
  • Vue で resetFields() を使用する際の注意事項について簡単に説明します。
  • Vue の vue.$set() メソッドのソースコード例の詳細な説明

<<:  Oracle の開閉の 4 つのモード

>>:  Linux TTY/PTS の違いの概要

ブログ    

推薦する

ドロップダウンメニューを表示または非表示にするJavaScript

この記事では、ドロップダウンメニューを表示および非表示にするJavaScriptの具体的なコードを参...

MySQLで現在の時間間隔の前日のデータをクエリする

1. 背景実際のプロジェクトでは、分散スケジュールされたタスク実行の状況に遭遇することがあります。ス...

マークアップ言語 -

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

MySQLサービスを削除する具体的な方法

MySQLは次のエラーを表示します「コントロール パネル -> 管理ツール -> サービ...

Linux redis-Sentinel 設定の詳細

ダウンロードダウンロードアドレス: https://redis.io/download /usr/l...

Linux での Tomcat8 のインストールとアンインストールに関する詳細なグラフィック チュートリアル

[ Tomcat8 の Linux インストール ] Tomcat をアンインストールする - まず...

ランダムロールコールテーブルを実装するためのネイティブJavaScript

この記事では、JavaScriptのランダムロールコールテーブルの具体的なコードを参考までに紹介しま...

js QRコードスキャンログインの原理についての簡単な説明

目次QRコードログインの真髄QRコードを理解するシステム認証メカニズムQRコードをスキャンしてログイ...

CSS3 フリップカード番号サンプルコード

今日会社から課題をもらったのですが、効果図は以下のとおりです。 どのような効果を実現したいかは特に決...

JavaScript で文字列内の最長の単語を見つける 3 つの方法 (推奨)

この記事は、Free Code Camp の基本アルゴリズム スクリプト「文字列内の最長の単語を見つ...

JSにおけるnewの原理と実装について詳しく話しましょう

目次意味コンストラクタ本体は異なる戻り値なし戻りオブジェクト非オブジェクトを返すプロパティバインディ...

MySQL 整合性制約の定義と例のチュートリアル

目次整合性制約整合性制約の定義整合性制約の分類主キー制約単一の主キーと複合主キーの違い主キーフィール...

jQuery における Ajax の関連知識ポイントのまとめ

序文JavaScriptを学ぶ学生は、 AJAX (非同期JavaScriptとxml) 変換は非同...

MySQL の非主キー自己増分使用例の分析

この記事では、例を使用して、MySQL の非主キーの自己増分の使用方法を説明します。ご参考までに、詳...

Vue3はJingdong製品詳細ページの虫眼鏡効果コンポーネントをカプセル化します

この記事では、Jingdong製品詳細ページの虫眼鏡効果コンポーネントに似たvue3カプセル化の具体...