概要Vue は軽量のフロントエンド フレームワークであり、その中核はコンポーネントベースの開発であることは誰もが知っています。 Vue はコンポーネントから構成されています。コンポーネント化は Vue の本質であり、最も強力な機能の 1 つです。コンポーネント インスタンスのスコープは互いに独立しているため、異なるコンポーネント間のデータは相互に参照できません。 しかし、実際のプロジェクト開発プロセスでは、他のコンポーネントのデータにアクセスする必要があるため、コンポーネント通信の問題が発生します。 Vue 内のコンポーネント間の関係は、父と子、兄弟、世代間の関係です。異なる関係でのデータ転送を実現する方法については、次に説明します。 1. 親コンポーネントが子コンポーネントに値を渡すつまり、親コンポーネントは属性を通じて子コンポーネントに値を渡し、子コンポーネントは props を通じて値を受け取ります。 親コンポーネントの子コンポーネントタグにカスタムプロパティをバインドする // 親コンポーネント <user-detail :myName="name" /> エクスポートデフォルト{ コンポーネント: ユーザー詳細 } ...... } 子コンポーネントでそれを受け取るには、props (配列またはオブジェクト) を使用します。複数の属性を渡すことが可能です。 // サブコンポーネントエクスポートデフォルト{ プロパティ: ['myName'] } /* props: { myName: String } //この方法で渡される型を指定します。型が正しくない場合は警告が発行されます props: { myName: [String, Number] } // 複数の型が考えられます prosp: { myName: { type: String, requires: true } } //必須の文字列 props: { 子メッセージ: { タイプ: 配列、 デフォルト: () => [] } } // default はデフォルト値を指定します。props の検証に失敗した場合は、コンソールに警告が表示されます。 */ 子コンポーネントが受け取る親コンポーネントの値は、参照型と共通型に分けられます。 一般的な型: 文字列、数値、ブール値、Null 参照型: 配列、オブジェクト Vue の一方向データフローに基づいて、つまり、コンポーネント間のデータは一方向であり、子コンポーネントは親コンポーネントによって渡された値を直接変更することはできません。そのため、親コンポーネントによって渡された値を直接変更するこの操作は避ける必要があります。そうしないと、コンソールにエラーが報告されます。 渡された値が単純なデータ型の場合、親コンポーネントから値を呼び出す他の兄弟コンポーネントに影響を与えることなく、子コンポーネントで値を変更できます。 具体的な操作は、まず渡された値をデータ内の変数に再割り当てし、次にその変数を変更することです。 // サブコンポーネントエクスポートデフォルト{ プロパティ: ['myName'], データ() { 戻る { name : this.myName // 渡された値を新しい変数に代入します} }, 時計: myName(新しい値) { this.name = newVal //親コンポーネントから渡された値をリッスンし、変更された場合は子コンポーネント内の値も変更します} }, メソッド: { 名前を変更する() { this.name = 'Lily' // ここでは内部値のみが変更されるため、エラーは報告されません}, } } 注: 親コンポーネントから渡される myName 値を監視するために watch を使用しない場合、データ内の name: this.myName は初期値のみを定義するため、子コンポーネントの name 値は親コンポーネントの myName 値によって変更されません。 子コンポーネントで参照型の値が変更されると、そのデータはパブリックであるため親コンポーネントも変更され、その値を参照する他の子コンポーネントも変更されます。親コンポーネントから子コンポーネントに渡される値はコピーを作成することと同等であり、このコピーのポインターは依然として親コンポーネント内のポインターを指している、つまり同じ参照を共有していることがわかります。したがって、特別な必要がない限り、簡単に変更しないでください。 2. 子コンポーネントが親コンポーネントに値を渡す1. サブコンポーネントはイベントをバインドし、this.$emit() を通じてそれをトリガーします。子コンポーネントにイベントをバインドし、このイベントの関数を定義します。 // 子コンポーネント <button @click="changeParentName">親コンポーネントの名前を変更する</button> エクスポートデフォルト{ メソッド: { //サブコンポーネントイベント changeParentName: function() { this.$emit('handleChange', 'Jack') // 親コンポーネントでhandleChangeイベントをトリガーし、それをJackに渡します // 注意: ここでのイベント名は、親コンポーネントにバインドされたイベント名と一致している必要があります} } } 親コンポーネントでhandleChangeイベントを定義してバインドする // 親コンポーネント <child @handleChange="changeName"></child> メソッド: { changeName(name) { // nameパラメータは子コンポーネントJackから渡された値です this.name = 名前 } } 2. コールバック関数を通じてまず親コンポーネントにコールバック関数を定義し、そのコールバック関数を渡します。 // 親コンポーネント <child :callback="callback"></child> メソッド: { コールバック: 関数(名前) { this.name = 名前 } } 子コンポーネントで受信し、コールバック関数を実行する // 子コンポーネント <button @click="callback('Jack')">親コンポーネントの名前を変更する</button> 小道具: { コールバック: 関数、 } 3. $parent / $children または $refs 経由でコンポーネントインスタンスにアクセスするどちらのメソッドもコンポーネント インスタンスを直接取得し、使用後にコンポーネント メソッドを呼び出したり、データに直接アクセスしたりできます。 // サブコンポーネントエクスポートデフォルト{ データ () { 戻る { タイトル: 'サブコンポーネント' } }, メソッド: { こんにちは(){ console.log('こんにちは'); } } } // 親コンポーネント <テンプレート> <childref="childRef" /> </テンプレート> <スクリプト> エクスポートデフォルト{ 作成された(){ // $ref を介して子コンポーネントにアクセスします console.log(this.$refs.childRef.title); // 子コンポーネント this.$refs.childRef.sayHello(); // Hello // $children を通じて子コンポーネントメソッドを呼び出す this.$children.sayHello(); // Hello } } </スクリプト> 注意: この方法でのコンポーネント通信はレベルを越えることはできません。 3. 兄弟コンポーネント間で値を転送する1. $emitとpropsの組み合わせにより親コンポーネントでは、2つの兄弟コンポーネントに渡される変数をバインドし、イベントを定義します。 // 親コンポーネント <child-a :myName="name" /> <child-b :myName="名前" @changeName="名前を編集" /> エクスポートデフォルト{ データ() { 戻る { 名前: 'ジョン' } }, コンポーネント: 'child-a': 子A、 'child-b': 子B、 }, メソッド: { editName(名前) { this.name = 名前 }, } } 子コンポーネントBで変数を受け取り、トリガーイベントをバインドする // 子 b コンポーネント<p>名前: {{ myName }}</p> <button @click="changeName">名前を変更</button> <スクリプト> エクスポートデフォルト{ プロパティ: ["myName"], メソッド: { 名前を変更する() { this.$emit('changeName', 'Lily') // イベントをトリガーして値を渡す} } } </スクリプト> // 子コンポーネント<p>名前: {{ newName }}</p> <スクリプト> エクスポートデフォルト{ プロパティ: ["myName"], 計算: { 新しい名前() { if(this.myName) { // 渡された値があるかどうかを確認します return this.myName } return 'John' //値が渡されない場合はデフォルト値} } } </スクリプト> つまり、子コンポーネント B が $emit() を通じて親コンポーネントのイベント関数 editName をトリガーし、親コンポーネントの変数名の値を変更すると、親コンポーネントは props を通じて変更された値を子コンポーネント A に渡すことができ、兄弟コンポーネント間のデータ転送を実現できます。 2. 空のvueインスタンスを介してEventBus.jsファイルを作成し、vueインスタンスを公開する 'Vue' から Vue をインポートします デフォルトの新しい Vue() をエクスポートします この空のvueインスタンスをファイルにインポートして値を渡し、イベントをバインドし、$emitを介してイベント関数をトリガーします。 (main.js で js ファイルをグローバルにインポートすることもできます。私は通常、使用する必要があるコンポーネントでインポートします。) <テンプレート> <div> <p>名前: {{ name }}}</p> <button @click="changeName">名前を変更</button> </div> </テンプレート> <スクリプト> 「../EventBus.js」から{EventBus}をインポートします。 エクスポートデフォルト{ データ() { 戻る { 名前: 'ジョン'、 } }, メソッド: { 名前を変更する() { this.name = 'リリー' EventBus.$emit("editName", this.name) // グローバル イベントをトリガーし、変更された値をイベント関数に渡します} } } </スクリプト> 値を受け取るコンポーネントに vue インスタンスをインポートし、$on を介してコールバックをリッスンします。コールバック関数は、イベントがトリガーされたときに渡されるすべてのパラメーターを受け取ります。 「../EventBus.js」から{EventBus}をインポートします。 エクスポートデフォルト{ データ() { 戻る { 名前: '' } }, 作成された() { EventBus.$on('editName', (名前) => { this.name = 名前 }) } } 空の vue インスタンスを作成するこの方法は、イベントを送受信するためのイベント センターまたは交通機関の駅を作成するのと同じです。この方法は、親子、兄弟、クロスレベルなど、コンポーネント間のあらゆる通信にも適用できます。通信要件が単純なプロジェクトには便利ですが、より複雑な状況や大規模なプロジェクトの場合は、Vue が提供するより複雑な状態管理モード Vuex を使用して処理できます。 4. 多層親子コンポーネント通信場合によっては、通信する必要がある 2 つのコンポーネントが直接の親子コンポーネントではなく、祖父と孫、または複数のレベルにまたがる親子コンポーネントであることがあります。この場合、子コンポーネントが一度に 1 レベルずつパラメータを上位に渡すことは不可能です。特に、コンポーネント階層が深く、ネストされたコンポーネントが多数ある場合は、渡す必要のあるイベントと属性が多くなり、コードが非常にわかりにくくなります。 このとき、Vue が提供するより高レベルのメソッドである provide/inject を使用する必要があります。 このオプションのペアは、コンポーネント階層の深さに関係なく、祖先コンポーネントがそのすべての子孫に依存関係を注入できるようにするために一緒に使用する必要があります。また、上流と下流の関係が維持されている限り常に機能します。 提供/注入: 簡単に言うと、変数は親コンポーネントのプロバイダーを通じて提供され、その後、注入を通じて子コンポーネントに注入されます。コンポーネント階層の深さに関係なく、変数は親コンポーネントのライフサイクル中は常に有効です。 親コンポーネント: エクスポートデフォルト{ provide: { // その機能は、変数 **name** をすべての子コンポーネントに提供することです。 名前: 'ジャック' } } サブコンポーネント: エクスポートデフォルト{ inject: ['name'], // 親コンポーネントによって提供される名前変数を注入します。mounted() { console.log(this.name); // ジャック } } 注意: provide および inject バインディングはリアクティブではありません。つまり、親コンポーネントの名前が変更されても、子コンポーネントはそれに応じて変更されません。 データ応答を提供して挿入する場合、次の 2 つの方法があります。 祖先コンポーネントのインスタンスを用意し、子孫コンポーネントに依存関係を注入することで、祖先コンポーネントインスタンスのプロパティを子孫コンポーネントで直接変更できるようになります。ただし、この方法には、このインスタンスに props やメソッドなど不要なものが多くマウントされるという欠点があります。 // 親コンポーネント <div> <button @click="changeName">名前を変更</button> <子-b /> </div> <スクリプト> ...... データ() { 戻る { 名前: 「ジャック」 }; }, 提供する() { 戻る { parentObj: this // 祖先コンポーネントのインスタンスを提供する}; }, メソッド: { 名前を変更する() { this.name = 'リリー' } } </スクリプト> 子孫コンポーネントの値: <テンプレート> <div class="border2"> <P>名前: {{parentObj.name}}</P> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ 注入: { 親オブジェクト: { デフォルト: () => ({}) } } // または inject: ['parentObj'] }; </スクリプト> 注: このメソッドは、機能コンポーネントでよく使用されます。機能コンポーネントは、ステートレス(応答データなし)、インスタンス化なし(this コンテキストなし)、内部にライフサイクル処理メソッドがありません。そのため、レンダリング パフォーマンスが高く、外部データ転送に依存するコンポーネントに適しています。 要約する親子間の通信: 親は props を通じて子にデータを渡し、子は $emit を通じて親にデータを渡します。$parent / $children を通じて通信します。$ref はコンポーネント インスタンスにもアクセスできます。$attrs / $listeners を提供/注入します。 兄弟通信: EventBus; Vuex; クロスレベル通信: EventBus、Vuex、provide / inject、$attrs / $listeners、 以上が、Vue コンポーネント同士がどのように値を渡すのかの詳しい説明です。Vue についてさらに詳しく知りたい方は、123WORDPRESS.COM 内の他の関連記事もぜひご注目ください! 以下もご興味があるかもしれません:
|
<<: Linux の運用と保守で netstat の代わりに ss コマンドを使用する方法
>>: 今日と昨日の 0:00 タイムスタンプを取得する MySQL の例
序文プロジェクトのニーズに応じて、Vue-touch を使用して、vue モバイル端末の左スワイプ編...
機能: 前のページまたは次のページにジャンプします。要素: ページングの基本要素は、前のページ + ...
JavaScript に依存せず、純粋な CSS を使用してsvgストローク描画アニメーション効果と...
今日、インターフェースの同時実行の問題を検証したところ、これまでredisで解決していた同時実行のプ...
シナリオ最近の要件は、モバイル デバイス用の h5 ページです。これには、選択可能なカードの行が必要...
導入アニメーションを使用すると、JavaScript や jQuery に依存せずに、純粋な CSS...
以下のように表示されます。主に認証コマンドを実行します: 2つの方法1. 任意のホストがユーザー b...
1. 約束の説明Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を...
背景Shell の mysql-client を介して MySQL データベースにログインする場合、...
> MySQL 5.7 クラスタ マスターとスレーブをデプロイする (テストのみ)イメージバー...
今日は、MySQL をインストールしたかったので、公式 Web サイトにアクセスして、MySQL の...
これは私の最初のブログ投稿です。時間の制約があるため、どのようにフォーマットすればよいかわかりません...
序文最近、仕事の都合で、約 1000w の大量のデータを MySQL に挿入する必要があり、時間がか...
【質問】外側のテーブルと内側のテーブルがネストされていて、内側のテーブルと外側のテーブルの両方に境界...
プロジェクトシナリオプロジェクトの背景全体にカスタム透かしを追加します。透かしのテキスト、フォントの...