Vueの子コンポーネントと親コンポーネントの詳細な分析

Vueの子コンポーネントと親コンポーネントの詳細な分析

1. 親コンポーネントと子コンポーネント

親コンポーネントと子コンポーネントが何であるかがわからないことがよくあります。簡単にまとめると、コードの一部をコンポーネントにカプセル化し、このコンポーネントを別のコンポーネントに導入します。カプセル化されたコンポーネントを導入するファイルは親コンポーネントと呼ばれ、導入されるコンポーネントは子コンポーネントと呼ばれます。

具体的なコードは次のとおりです。

<div id="アプリ">
  <コンポーネント2></コンポーネント2>
</div>
<スクリプト>
  // グローバル登録 Vue.component("component1", {
    テンプレート: `
    <div>
      <h2>こんにちは</h2>
    </div>
    `
  })

  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      メッセージ: 「こんにちは」
    },
    コンポーネント:
      // ローカル登録 "component2": {
        テンプレート: `
            <div>
              <コンポーネント1></コンポーネント1>
              <h2>世界</h2>
            </div>
        `、
      }
    }
  })
</スクリプト>
  • 1. コンポーネントcomponent1をグローバルに登録する
  • 2. コンポーネントcomponent2ローカルに登録し、コンポーネントcomponent1component2で参照される

最後に、HTML でコンポーネントcomponent-2を使用します。

テンプレートコードは次のとおりです。

<div>
  <コンポーネント-1></コンポーネント-1>
  <h2>世界</h2>
</div>


コンポーネントcomponent1もテンプレートがあるため、プログラムはそれを自動的に解析し、 component-2の最終的なhtmlコードは次のようになります。

<div>
  <div>
      <h2>こんにちは</h2>
    </div>
  <h2>世界</h2>
</div>


したがって、ブラウザに表示される効果は次のようになります。

こんにちは
世界

結果:

component1は子コンポーネント、 component2は親コンポーネントです

2. テンプレート分離書き込み

上記のコンポーネントを作成した際、コンポーネント内にtemplateを記述しました。しかし、コンパイラーで記述すると、コードプロンプトが出ないだけでなく、改行が揃わず、記述が非常に面倒でした。そこで、ここではテンプレート分離記述法を紹介します。

1. テンプレートタグ

コンポーネントに元々記述されているtemplateを抽出し、それをhtmlに配置し、 templateタグを使用して、次のように id 属性を添付します。

<テンプレートid="component2">
  <div>
    <コンポーネント1></コンポーネント1>
    <h2>世界</h2>
  </div>
</テンプレート>

次に、コンポーネント内で、元のtemplateタグの内容を id に置き換えて、プログラムが対応する id テンプレートを自動的に見つけられるようにします。

コンポーネント:
  // ローカル登録 "component2": {
    テンプレート: `#component2`,
  }
}

この書き方を推奨する

2. テキスト/xテンプレート

上記に似た別の書き方もあります。上記ではtemplateタグを使用しました。この書き方では、 templateのコンテンツをscriptタグに配置し、type type=text/x-templateを指定して、id 属性を指定するだけです。

次のように:

<script type="text/x-template" id="component2">
  <div>
    <コンポーネント1></コンポーネント1>
    <h2>世界</h2>
  </div>
</スクリプト>
 

3. 親子コンポーネント通信 - 親子

親コンポーネントと子コンポーネントを作成するときに、子コンポーネントも親コンポーネントと同じデータを取得したい場合、1 つの方法は、データを取得するためにインターフェイスをバックグラウンドに送信することですが、これはサーバーに負担をかけるため、2 番目の方法として、 props属性を介して親コンポーネントのデータを取得します。

<div id="アプリ">
  <test1 :cmovies="映画"></test1>
</div>
<テンプレートid="test1">
  <div>
    <ul>
      <li v-for="cmovies 内のアイテム">{{item}}</li>
    </ul>
  </div>
</テンプレート>
<スクリプト>
  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      映画:[「ワンピース」、「海爾兄弟」、「海王類」]
    },
    コンポーネント:
      "テスト1": {
        テンプレート: `#test1`,
        小道具: ['cmovies'],
        データ(){
          戻る{}
        },
      }
    }
  })
</スクリプト>

ここでは、 appインスタンスを親コンポーネント、子コンポーネントtest1として定義しています。子コンポーネントtest1親コンポーネントdataのデータを取得してページに表示したい場合は、 props 属性を記述する必要があります。ここでは、変数 cmovies がバインドされています。最後に、子コンポーネントtest1 HTML で使用するときに、親コンポーネントdataのデータを渡す場合は、属性,:cmovies="movies",cmoviesは props で定義された変数であり、バインドされた値は movies リストです。したがって、 <li v-for="item in cmovies">{{item}}</li>中的cmoviessの値は、実際にはリストmoviesのデータです。親コンポーネントが子コンポーネントに値を渡したためです。

最後に、ムービー内のムービーを Web ページに表示できます。

上記のページに示されている順序なしリストでは、子コンポーネントを使用しています。データは親コンポーネントのdataから子コンポーネントに渡され、子コンポーネントはprops

1. プロップタイプ

上記の例では、親コンポーネントからデータを受け取るための配列としてpropsを定義します。代わりにオブジェクトを使用することもできます。これにより、型の検出、カスタム検証、デフォルト値の設定などの高度なオプションを構成できます。

  • type: は、次のネイティブ コンストラクターのいずれかになります: String、Number、Boolean、Array、Object、Date、Function、Symbol 、任意のカスタム コンストラクター、または上記の配列。 propが指定されたタイプであるかどうかを確認し、そうでない場合は警告をスローします。 Propタイプの詳細については、こちらをご覧ください。
  • default: any propのデフォルト値を指定します。このpropが渡されない場合、代わりにこの値が使用されます。オブジェクトまたは配列のデフォルト値はファクトリ関数から返される必要があります。
  • required: Boolean propが必須かどうかを定義します。非本番環境では、値がtruthyであり、 propが渡されない場合、コンソール警告がスローされます。
  • validator: Functionカスタム検証関数は、 propの値を唯一のパラメーターとして置き換えます。非本番環境では、この関数が偽の値を返す場合 (つまり、検証が失敗する)、コンソールに警告がスローされます。 prop検証の詳細については、こちらをご覧ください。

例:

// シンプルな構文 Vue.component('props-demo-simple', {
  プロパティ: ['size', 'myMessage']
})

// 検証を提供するオブジェクト構文 Vue.component('props-demo-advanced', {
  小道具: {
    // 検出タイプの高さ: 数値、
    // 検出タイプ + その他の検証年齢: {
      タイプ: 数値、
      デフォルト: 0,
      必須: true、
      バリデータ: 関数 (値) {
        戻り値 >= 0
      }
    }
  }
})

注意: propsを使用する場合、 cMoviesなどのキャメルケースを使用してHTMLにバインドし、次のように記述すると、プログラムはそれを認識しません。 c-movies

4. 親子コンポーネント通信

子から親へのシナリオでは、子コンポーネントは通常、イベントを親コンポーネントに渡してリッスンし、ユーザーがどのボタンをクリックしたかを親コンポーネントに伝えます。使用される関数は$emitです。

1. vm.$emit( ​​イベント名、[…引数] )

パラメータ:

  • eventName:イベント名
  • args:長さが不定の配列

現在のインスタンスでイベントをトリガーします。追加のパラメータはリスナー コールバックに渡されます。

例:

<div id="アプリ">
  <test1 @item-click="cpnClick"></test1>
</div>
<テンプレートid="test1">
  <div>
    <button v-for="カテゴリ内のアイテム" @click="btnClick(item)">{{item.name}}</button>
  </div>
</テンプレート>
<スクリプト>
  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      メッセージ: 「こんにちは」
    },
    メソッド: {
      cpnClick(アイテム){
        console.log("成功", 項目)
      }
    },
    コンポーネント:
      // ローカル登録コンポーネント test1
      "テスト1": {
        データ(){
          戻る {
            カテゴリー: [
              {id: "aaa", name: "ホットなおすすめ"},
              {id: "bbb", 名前: "モバイルデジタル"},
              {id: "ccc", name: "家電製品"},
              {id: "ddd", 名前: "食品・飲料"},
            ]
          }
        },
        メソッド: {
          btnClick(アイテム){
            this.$emit("item-click", item)
          }
        },
        テンプレート: `#test1`
      }
    }
  })
</スクリプト>

上記のコードは、 test1子コンポーネントを定義し、 methodsの $ emitを通じてイベントと追加パラメータitemを渡します。次に、親コンポーネントは@item-click="cpnClick"を通じてイベントをバインドし、親コンポーネントが子コンポーネントのクリック イベントを受信して​​独自のクリック イベントをトリガーできるようにします。効果は次のようになります。


コンソールによって出力されるログにはサブコンポーネントのcategoriesが含まれていることがわかります。

5. 親子コンポーネント通信 - 双方向バインディングケースと組み合わせる

次の例では、親から子、子から親、およびv-modelを組み合わせた、非常に包括的な例です。

1. 基本的なテンプレートコード

<div id="アプリ">
  <cpn :number1="num1" :number2="num2"></cpn>
</div>
<テンプレートid="cpn">
  <div>
    <h2>{{番号1}}</h2>
    <h2>{{数値2}}</h2>
  </div>
</テンプレート>
<スクリプト>
  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      数値1: 0,
      数値2: 1,
    },
    コンポーネント:
      // サブコンポーネント cpn を定義する
      "cpn": {
        テンプレート: `#cpn`,
        小道具: {
          数値1: 数値、
          数値2: 数値、
        }
      }
    },
  })
</スクリプト>

コードは次のことを行います

  • 1. 子コンポーネントcpnを定義し、親コンポーネントから渡されるデータを受け取るための2つの属性number1number2を定義します。
  • 2. サブコンポーネントcpnはhtmlコードで参照され、アプリの強度のnum1とnum2はサブコンポーネントpropsのプロパティに渡されます。
  • 3. 最後に、ページに表示されるデータnumber1と番号2は、実際にはデータ内のnum1とnum2です。

最終的なページ表示効果は次のとおりです。

0
1

2. 双方向バインディングを追加する

上記のテンプレートに基づいて、双方向バインディングを追加し、 2 inputタグを追加し、 v-modelを使用してpropsの属性とバインドします。

<テンプレートid="cpn">
  <div>
    <h2>小道具:{{number1}}</h2>
    <input type="text" v-model="number1">
    <h2>小道具:{{number2}}</h2>
    <input type="text" v-model="number2">
  </div>
</テンプレート>

上記のコードは双方向バインディングを完了しますが、エラー警告が表示されます。

子コンポーネントでpropsを使用した双方向バインディングを使用すると、 props双方向バインディングを使用しないように警告が表示されます。双方向バインディングには、 dataまたはcompused使用することをお勧めします。ここでは、これをdataバインディングに変更します。

<テンプレートid="cpn">
  <div>
    <h2>データ:{{dnumber1}}</h2>
    <input type="text" v-model="dnumber1">
    <h2>データ:{{dnumber2}}</h2>
    <input type="text" v-model="dnumber2">
  </div>
</テンプレート>
データ(){
   戻る {
     dnumber1: this.number1,
     dnumber2: this.number2,
   }
},

dataにバインドすると、エラーは発生しません。

3. 逆バインディング

上記の考え方に従うと、 input値が変更されたときに、親コンポーネントのnum1num2の値もdata内で同時に変更されることを期待します。このとき、子から親に値を渡すためにリバースバインディングが必要です。

完全なコードは次のとおりです。

<div id="アプリ">
  <cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change"></cpn>
</div>
<テンプレートid="cpn">
  <div>
    <h2>小道具:{{number1}}</h2>
    <h2>データ:{{dnumber1}}</h2>
    <ラベル>
      <input type="text" :value="dnumber1" @input="num1Input">
    </ラベル>
    <h2>小道具:{{number2}}</h2>
    <h2>データ:{{dnumber2}}</h2>
    <ラベル>
      <input type="text" :value="dnumber2" @input="num2Input">
    </ラベル>
  </div>
</テンプレート>
<スクリプト>
  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      数値1: 0,
      数値2: 1,
    },
    メソッド: {
      num1変更(値){
        this.num1 = parseInt(値)
      },
      num2change(値){
        this.num2 = parseInt(値)
      },
    },
    コンポーネント:
      // サブコンポーネント cpn を定義する
      "cpn": {
        テンプレート: `#cpn`,
        小道具: {
          数値1: 数値、
          数値2: 数値、
        },
        データ(){
          戻る {
            dnumber1: this.number1,
            dnumber2: this.number2,
          }
        },
        メソッド: {
          num1Input(イベント){
            // 1. 入力の値をdnumberに代入します。this.dnumber1 = event.target.value
            // 2. 親コンポーネントが値を変更するには、イベントを発行する必要があります this.$emit("num1change", this.dnumber1)
          },
          num2Input(イベント){
            // 1. 入力の値をdnumberに代入します。this.dnumber2 = event.target.value
            // 2. 親コンポーネントが値を変更するには、イベントを発行する必要があります this.$emit("num2change", this.dnumber2)
          }
        }
      }
    },
  })
</スクリプト>

効果は以下のとおりです。

6. コンポーネントの親アクセスから子アクセス

親コンポーネントで子コンポーネントの関数または属性値を使用する必要がある場合は、 Objectを返す$refsを使用できます。まず、次のコードを見てみましょう。

<div id="アプリ">
  <cpn ref="aaa"></cpn>
  <button @click="btnClick">ボタン</button>
</div>
<テンプレートid="cpn">
  <div>
    私は子コンポーネントです</div>
</テンプレート>
<script src="../js/vue.js"></script>
<スクリプト>
  constアプリ = 新しいVue({
    el: "#app",
    データ: {
      メッセージ: 「こんにちは」
    },
    メソッド: {
      btnClick(){
        console.log(this.$refs.aaa.name)
        this.$refs.aaa.showMessage()
      }
    },
    コンポーネント:
      "cpn": {
        テンプレート: `#cpn`,
        データ(){
          戻る {
            name: 「私はサブコンポーネントの名前です」
          }
        },
        メソッド: {
          表示メッセージ(){
            console.log("メッセージを表示")
          }
        }
      }
    }
  })
</スクリプト>

上記のコードは以下のことを行います

  • 1. メソッドshowMessageと属性nameを定義するコンポーネントcpnを作成しました。
  • 2. 子コンポーネントcpn親コンポーネントで使用され、属性refaaaがバインドされます。これは一意の識別子に相当します。
  • 3. 親コンポーネントのbtnClickメソッドは、子コンポーネントのメソッドとプロパティを使用する必要があります。必要なのはthis.$refs.aaaだけです。ここで、aaa は上にバインドされた子コンポーネントのプロパティです。
  • 4. 最後に、 this.$refs.aaa.nameを使用してサブコンポーネントのname属性を使用します。

これで、Vue の子コンポーネントと親コンポーネントの詳細な分析に関するこの記事は終了です。より関連性の高い Vue の子コンポーネントと親コンポーネントについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

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

<<:  W3C チュートリアル (14): W3C RDF および OWL アクティビティ

>>:  CSSスクロールバーのスタイルをカスタマイズする方法の詳細な説明

推薦する

Mysqlアカウント管理の原理と実装方法の詳細な説明

この記事では、例を使用して、MySQL アカウント管理の原則と実装方法を説明します。ご参考までに、詳...

時間のかかるDockerエラーのトラブルシューティングプロセス記録

目次起源環境情報トラブルシューティングのプロセス要約する起源顧客は CentOS をベースにしたカス...

LinuxでのMySQLのインストール手順

1. mysql tar ファイルをダウンロードします。参考: 2. インストールパッケージがあるデ...

JavaScriptのアンチシェイクとスロットリングとは

目次1. 関数デバウンス1. 画像安定化とは何ですか? 2. 関数のスロットリング2.1 タイマーの...

VirtualBox仮想マシンがNATモードで外部ネットワークに接続できない問題の解決策

背景VirtualBox 仮想マシン (Ubuntu 16.04 システムがロードされている) には...

MySQL 変数宣言とストアド プロシージャの分析

変数の宣言グローバル変数の設定@a='新しい変数' を設定します。関数やストアドプロ...

Nginx の http リソース リクエスト制限の詳細な説明 (3 つの方法)

前提条件: nginx には、ngx_http_limit_conn_module モジュールと n...

Mysql 複数データベースのバックアップ コード例

この記事は主にMysqlの複数データベースのバックアップのコード例を紹介します。この記事ではサンプル...

JS におけるメモリと変数の保存についての詳細な説明

目次序文JSマジックナンバー数値の保存バイナリ変換方法なぜ 0.1 + 0.2 !== 0.3 なの...

DOCTYPE要素詳細説明完全版

1. 概要この記事では、DOCTYPE要素を体系的に説明します。同時に、多くの情報を調べました。イン...

Linux のさまざまなロックメカニズムの使用方法と違いについて詳しく説明します

序文:この知識を理解する必要がある人は、すでにプロセス間通信とスレッド間通信の基本的な理解を持ってい...

Vue でメニュー権限制御を実装するためのサンプルコード

バックエンド管理システムで作業している場合、通常、メニュー権限制御に関連する問題に遭遇します。もちろ...

WeChatアプレットが検索ボックス機能を実装

この記事の例では、WeChatアプレットの検索ボックス機能を実装するための具体的なコードを参考までに...

UbuntuはSSHサービスのリモートログイン操作を開始します

ssh-secure シェルは、安全なリモート ログインを提供します。組み込みシステムを開発し、Li...

CSS を使用して固定左列と適応右列の 2 列レイアウトを実現する 4 つの方法

1. フロート+オーバーフロー:非表示このメソッドは主にオーバーフローを通じて BFC をトリガーし...