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スクロールバーのスタイルをカスタマイズする方法の詳細な説明

推薦する

MySQL8.0.18 複数マスターと 1 スレーブの構成

目次1. 現実的な背景2. 合意3. マスターを構成する3.1. 起動パラメータの設定3.2. パラ...

Docker クロスホストネットワーク (オーバーレイ) の実装

1. Dockerのホスト間通信Docker クロスホスト ネットワーク ソリューションには以下が含...

MYSQL メタデータ ロック (MDL ロック) の理論とロック タイプ テスト

目次MYSQL メタデータ ロック (MDL ロック) 学習理論とロック タイプ テスト1. 予備的...

JS における for、for...in、for...of、forEach の違いと使用例

forループ基本的な構文形式: for(変数の初期化; 条件式; 演算式){ループ本体ステートメント...

純粋なCSSでは、子要素が親要素の幅制限を突破できる。

文章のスタイルでは、このような状況がよく見られます コードは次のとおりです <div styl...

Vue 開発プロジェクトで Font Awesome 5 を使用する方法

目次依存関係をインストールする構成使用1.アイコン検索ページに入る2. 使用したいアイコンの英語名を...

VMware 仮想マシンでの Centos8 ブリッジの静的 IP 設定方法

1. ネットワーク接続方法がブリッジされていることを確認する物理ネットワーク接続ステータスのコピーを...

Windows Server 2012 リモート デスクトップ ライセンス サーバーがライセンスを提供できず、リモート セッションが切断される

本日、会社の内部サーバーにログインしたところ、リモートアクセスができませんでした。エラー メッセージ...

フロントエンド プロジェクトのデフォルトのスクロール バー スタイルを変更する (概要)

スクロールバーのデフォルトスタイルを変更する必要があるプロジェクトを多数作成しましたが、プラグインを...

nginxのデフォルトポートを変更する方法の詳細な説明

まず設定ファイルがどこにあるか調べる nginx.confはどこにありますかこれらのディレクトリを調...

Linux コマンドにおける Ctrl+z、Ctrl+c、Ctrl+d の違いと使い方

Linux で Ctrl+c、Ctrl+d、Ctrl+z はどういう意味ですか? Ctrl+c と ...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

要素UIテーブルはドロップダウンフィルタリング機能を実現します

この記事の例では、要素UIテーブルにドロップダウンフィルタリングを実装するための具体的なコードを参考...

MySQL innodb_autoinc_lock_mode について

innodb_autoinc_lock_mode パラメータは、auto_increment 列を持...

CSS 完全な視差スクロール効果

1. 何ですか視差スクロールとは、複数の背景レイヤーを異なる速度で動かすことで、3次元のモーション...