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は大文字と小文字を区別します言葉を見れば信じられます。タイトルを見れば内容がわかります。 ...

vue3.0+echarts は 3 次元の縦棒グラフを実現します

序文: Vue3.0はechartsの3次元縦棒グラフを実装します結果: 実装手順: 1. echa...

React コンポーネント通信ルーティングパラメータ転送 (react-router-dom)

目次最近Reactを勉強していて、今は仕事でVueを使っています。学習の過程で、両者を比較して理解を...

Linux システムで HugePages をすばやく構成するための完全な手順

序文Linux システムの HugePages と Oracle データベースの最適化については、関...

Alibaba Cloud で静的ウェブサイトを素早く構築する方法

序文:ジュニアプログラマーとして、私は自分自身の個人ウェブサイトを構築し、それを他の人に見せることを...

HTML+CSSは、要素の位置までスクロールして読み込みアニメーション効果を表示します。

要素までスクロールするたびに読み込みアニメーションを追加するにはどうすればよいですか?初期パラメータ...

ウェブサイトデザインにおいて非常に重要な概念であるdiv+floatの分析

ウェブサイトの構築では、HTML と CSS に関するさまざまな問題に常に遭遇します。ウェブサイト ...

MySQL 8.0 における MySQL のインストールと新しいパスワード認証方法の詳細な説明

1. はじめにOracle が MySQL 8.0GA をリリースしました。海外での GA はリリー...

LeetCode の SQL 実装 (177. 給与が N 番目に高い)

[LeetCode] 177. 最も高い給与従業員テーブルからn番目に高い給与を取得する SQL ...

mysql maxとwhere間の実行問題の概要

mysql maxとwhereの間の実行の問題SQLを実行します: テーブル「grades」を作成し...

Vueは新しいウィンドウを開き、パラメータ転送のグラフィック例を実装します。

私が実現したい機能は、新しいウィンドウを開いて新しいページを表示することですが、パラメータを渡す必要...

MycliはMySQLコマンドライン愛好家にとって必須のツールです

マイクリMyCLI は、自動補完と構文の強調表示を備えた MySQL、MariaDB、および Per...

CSS に基づいて MaterialUI ボタン​​クリックアニメーションを実装し、それを React コンポーネントにカプセル化します。

序文フロントエンドフレームワークのヘビーユーザーとして、私はテクノロジーを選択する際にそのエコロジー...