序文親子コンポーネントの通信は、次の 2 つのケースに分けられます。 1. 親コンポーネントが子コンポーネントにデータを渡す 一般的に言えば、状況 1 のデータ転送の問題は props によって解決できるため、ここでは詳細には触れません。 子コンポーネントは親コンポーネントにデータを渡す主に2つのシナリオの実現について話しますが、方法は3つあります。 1. 親コンポーネントは、props を通じて、データとデータを変更する関数を子コンポーネントに渡します。子コンポーネントで親コンポーネントから渡された関数を呼び出すことで、親コンポーネントのデータが更新されます (親コンポーネントにデータが渡されます) (子コンポーネントでは対応する応答イベントが必要です) 2. 子コンポーネントでカスタムイベント(vm.$emit)をトリガーすると、v-on: [カスタムイベント]を使用してデータが親コンポーネントに返され、関数をリッスンします。 3. ref を通じて子コンポーネントをマークすると、親コンポーネントは vm.$refs.[子コンポーネント ref].[子コンポーネントのプロパティ/メソッド] を通じて子コンポーネントのデータを直接取得できます。 以下に一つずつ紹介します 1. 親コンポーネントから子コンポーネントにpropsを介して関数を渡し、親コンポーネントのデータを変更する関数を呼び出すここにはコードは表示されません まず、これは比較的単純であり、次に、これは明らかに Vue のベストプラクティスではありません (React ではより一般的です)。 2. カスタムイベントを通じて子コンポーネントから親コンポーネントにデータを渡す$emit(event, [...parameters]) を通じて子コンポーネントでカスタムイベントをトリガーできるため、親コンポーネントは v-on を直接使用して、子コンポーネントが使用されている場所で子コンポーネントによってトリガーされたイベントをリッスンし、リスニング関数で子コンポーネントから渡されたすべてのパラメータを順番に取得できます。 例えば: this.emit('eventYouDefined', arg); 次に、親コンポーネントの子コンポーネント テンプレートでリッスンできます。 <Son v-on: eventYouDefined = "functionYours" /> ここに例があります 親コンポーネント <テンプレート> <div id="父"> <div> 私は親コンポーネントであり、以下を受け取りました: {{ text || 'まだデータがありません' }} <son v-on:sendData='getSonText'></son> </div> </div> </テンプレート> <スクリプト> './son.vue' から son をインポートします。 エクスポートデフォルト{ データ: 関数 () { 戻る { 文章: '' } }, コンポーネント: 息子:息子 }, メソッド: { getSonText (テキスト) { this.text = テキスト } } } </スクリプト> <スタイルスコープ> #父 div { パディング: 10px; マージン: 10px; 境界線: 1px のグレー実線; オーバーフロー: 非表示; } </スタイル> サブコンポーネント: <テンプレート> <div> <p>私は子コンポーネントです。私が持っているデータは次のとおりです: {{ text }}</p> <ボタン @click="sendData"> データを送信</button> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ データ () { 戻る { テキスト: '子コンポーネントからのデータ' } }, メソッド: { 送信データ() { this.$emit('sendData', this.text) } } } </スクリプト> <!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します --> <スタイルスコープ> ボタン { float: 左 } </スタイル> 子コンポーネントの「データの送信」ボタンをクリックする前に、親コンポーネントがデータを受信していない(テキストが空の文字列)場合、{{ text || 'データはまだありません' }} はデフォルトのテキスト「データはまだありません」を表示します。 「データを送信」ボタンをクリックした後: sendDataカスタムイベントがトリガーされるため、 this.$emit('sendData', this.text) //ここでは子コンポーネントのインスタンスを指します) 子コンポーネントのテキスト データは親コンポーネントにあります。 <son v-on:sendData='getSonText'></son> コンポーネント内の getSonText 関数はパラメータをパラメータとして受け取り、子コンポーネントから親コンポーネントへのパラメータ転送プロセスを完了します。 3. ref属性を介して親コンポーネント内で子コンポーネントのデータを直接取得する上で説明した処理シナリオ 1 と 2 には、両方ともイベント メカニズム (クリックなどのネイティブ イベントかカスタム イベントか) に基づく必要があり、関数はイベントが発生したときにのみ呼び出されてデータを渡すことができるという制限があります。 しかし、子コンポーネントに「ボタン」のようなものが存在せず、ネイティブ イベントを作成できず、カスタム イベントをトリガーするタイミングを見つける方法がない場合は、どのようにして子コンポーネントから親コンポーネントにデータを渡すことができるのでしょうか。 ? 現時点では、ref属性を使用して親コンポーネントから子コンポーネントのデータを「直接取得」することしかできません。 Ref はよく使用する Vue 属性です。これを使用すると、このコンポーネントのテンプレートから DOM インスタンスを簡単に便利に取得できます。実際、親コンポーネントで子コンポーネントの ref を設定すると、vm.$refs.[子コンポーネントの ref].[子コンポーネントの属性] を通じてデータを直接取得できます。例: 親コンポーネント: <テンプレート> <div id="父"> <div> 私は親コンポーネントであり、以下を受け取りました: {{ text || 'まだデータがありません' }} <button @click="getSonText()">データを受け入れる</button> <息子ref='息子'></息子> </div> </div> </テンプレート> <スクリプト> './son.vue' から son をインポートします。 エクスポートデフォルト{ データ: 関数 () { 戻る { 文章: '' } }, コンポーネント: 息子:息子 }, メソッド: { テキストを取得する() { this.text = this.$refs.son.text } } } </スクリプト> <スタイルスコープ> #父 div { パディング: 10px; マージン: 10px; 境界線: 1px の灰色 オーバーフロー: 非表示; } </スタイル> サブコンポーネント: <テンプレート> <div> <p>私は子コンポーネントです。私が持っているデータ: {{ text }}</p> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ データ () { 戻る { テキスト: '子コンポーネントからのデータ' } } } </スクリプト> <!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します --> <スタイルスコープ> ボタン { float: 左 } </スタイル> デモ: 「データを受け入れる」ボタンをクリックする前に: 「データを受け入れる」ボタンをクリックした後: 同期を使用して双方向のデータバインディングを実現し、親子コンポーネントのデータを同期します。上記の 3 つの方法により、親子コンポーネントの通信シナリオのほとんどを解決できると思いますが、上記の通信シナリオを注意深く考えてみると、まだ問題があることがわかります。 子コンポーネントから親コンポーネントにデータを渡す場合、親コンポーネントと子コンポーネントのデータは常に同期されるわけではありません。 しかし、特別な要求のシナリオでは、親コンポーネントと子コンポーネントのデータを常に同期させたい場合があります。この場合、次のようにします。 これは親コンポーネントのテンプレートです: <son :foo="bar" v-on:update="val => bar = val"></son> 子コンポーネントでは、props宣言を通じてfooを受け取り、 小道具: { foo: [タイプ] } 同時に、サブコンポーネント内のデータが変更されるたびに、 this.$emit('update', newValue) 親コンポーネント テンプレートのリスニング関数の「val」にパラメーター newValue を渡します。そしてパス val => バー = val この式は、bar = newValue を実装します。この時点で、親コンポーネントのキー データ bar が子コンポーネントによって変更 (等しい) されていることがわかります。 双方向データバインディングにより、親(コンポーネント)は子のデータを変更でき、子も親のデータを変更できる。 Vue は上記のコードを簡略化するために sync 修飾子を提供します。次に例を示します。 <comp :foo.sync="bar"></comp> 次のように拡張されます: <comp :foo="bar" @update:foo="val => bar = val"></comp> 次に、子コンポーネント内の親コンポーネントのデータを変更する必要がある場合は、次のカスタム イベントをトリガーする必要があります。 this.$emit("update:foo", newValue) [注意] これは、前述の「カスタム イベント (emit) を介して子コンポーネントから親コンポーネントにデータを渡す」セクションの内容と重複しているように感じられるかもしれません。 しかし、そうではありません。両者の親子コンポーネント関係には違いがあります。以下では、重要なコード行を使用してその違いを証明します。 1. 同期について説明するセクションでは、カスタム イベントが発生したときに実行される応答式は次のとおりです。 2. 「カスタム イベントを通じて子コンポーネントから親コンポーネントにデータを渡す」の 2 番目の部分では、カスタム イベントが発生したときに実行される応答式は次のとおりです。 前者の場合、式 val => bar = val は、親コンポーネントのデータが子コンポーネントから渡されたデータと等しくなるように強制することを意味します。 このとき、親コンポーネントと子コンポーネントの状態が等しいことがわかります。 親は子(データ)を変更でき、子も親(データ)を変更できる 後者の場合、関数 Yours は親コンポーネントで定義されます。この関数では、子コンポーネントから受け取った arg データに対して任意の操作や処理を実行できます。決定権は完全に親コンポーネントにあります。つまり、親は子 (データ) を変更できますが、子は親 (データ) を直接変更することはできません。親のデータの変更は、それ自体によってのみ判断できる。 デモはこちらです: 親コンポーネント: <テンプレート> <div id="父"> <div> 私は親コンポーネントです<息子 :wisdom.sync="知恵" :magic.sync="マジック" :attack.sync="攻撃" :defense.sync="防御"> </息子> <p>知性: {{ 知恵 }}</p> <p>膜法: {{ magic }}</p> <p>攻撃: {{ attack }}</p> <p>防御: {{defense }}}</p> </div> </div> </テンプレート> <スクリプト> './son.vue' から son をインポートします。 エクスポートデフォルト{ データ: 関数 () { 戻る { 知恵: 90, 魔法: 160, 攻撃力: 100, 防御力: 80 } }, コンポーネント: 息子:息子 } } </スクリプト> <スタイルスコープ> #父 div { パディング: 10px; マージン: 10px; 境界線: 1px の灰色 オーバーフロー: 非表示; } </スタイル> サブコンポーネント: <テンプレート> <div> <p>私はサブコンポーネントです</p> <p>知性: {{ 知恵 }}</p> <p>膜法: {{ magic }}</p> <p>攻撃: {{ attack }}</p> <p>防御: {{defense }}}</p> <button @click="increment('wisdom')">知性を高める</button> <button @click="increment('magic')">膜を増やす方法</button> <button @click="increment('attack')">攻撃力を上げる</button> <button @click="increment('defense')">防御力を上げる</button> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ 小道具: { 知恵:数、 魔法: 数字、 攻撃: 数、 防御: 番号 }, メソッド: { 増分(データ名) { newValue = this[dataName] + 1 とします this.$emit(`update:${dataName}`, newValue) } } } </スクリプト> <!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します --> <スタイルスコープ> ボタン { float: 左 } </スタイル> クリック前 サブコンポーネントの追加で「インテリジェンスの増加」ボタンをクリックすると、親コンポーネントとサブコンポーネントの両方のインテリジェンス パラメータが 90 から 91 に変更されます。 「サブコンポーネントの追加」で「膜メソッドの追加」ボタンをクリックすると、親コンポーネントとサブコンポーネントのインテリジェンス パラメータが同時に 160 から 161 に変更されます。 双方向データバインディングは諸刃の剣である利点から: 1. 親子コンポーネントデータの「リアルタイム」同期を実現し、いくつかのデータシナリオで使用できます。 欠点としては: これにより、一方向のデータフローのシンプルさが損なわれ、データの分析の難易度が高まります。 同期によって変更されたプロパティがオブジェクトの場合上記の例を修正し、データをオブジェクトにラップして渡してみましょう。 親コンポーネント <テンプレート> <div id="父"> <div> 私は親コンポーネントです <son :analysisData.sync="analysisData"> </息子> <p>インテリジェンス: {{ analysisData.wisdom }}</p> <p>膜法: {{ analysisData.magic }}</p> <p>攻撃: {{ analysisData.attack }}</p> <p>防御: {{ analysisData.defense }}</p> </div> </div> </テンプレート> <スクリプト> './son.vue' から son をインポートします。 エクスポートデフォルト{ データ: 関数 () { 戻る { 分析データ: 知恵: 90, 魔法: 160, 攻撃力: 100, 防御力: 80 } } }, コンポーネント: 息子:息子 } } </スクリプト> <スタイルスコープ> #父 div { パディング: 10px; マージン: 10px; 境界線: 1px の灰色 オーバーフロー: 非表示; } </スタイル> サブコンポーネント <テンプレート> <div> <p>私はサブコンポーネントです</p> <p>インテリジェンス: {{ analysisData.wisdom }}</p> <p>膜法: {{ analysisData.magic }}</p> <p>攻撃: {{ analysisData.attack }}</p> <p>防御: {{ analysisData.defense }}</p> <button @click="increment('wisdom')">知性を高める</button> <button @click="increment('magic')">膜を増やす方法</button> <button @click="increment('attack')">攻撃力を上げる</button> <button @click="increment('defense')">防御力を上げる</button> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ 小道具: { 分析データ: オブジェクト }, メソッド: { 増分(データ名) { newObj = JSON.parse(JSON.stringify(this.analysisData)) とします。 新しいオブジェクト[データ名] += 1 this.$emit('update:analysisData', newObj) } } } </スクリプト> <!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します --> <スタイルスコープ> ボタン { float: 左 } </スタイル> 上記と同じデモ 子コンポーネントの参照型プロパティを変更することで、「親子コンポーネントのデータ同期」の要件を満たさないでください。親コンポーネントのデータは子コンポーネントに渡されますが、これは通常、props を通じて実現されます。「親子コンポーネントのデータ同期」の要件を実装する場合、子コンポーネント内の参照型 (配列やオブジェクトなど) の props を変更することが実現可能であることがわかります。 1. 親コンポーネントのデータを同時に変更できるだけでなく(同じデータが元々参照されているため) しかし、これを行わないでください。データフローの分析が非常に難しくなります。これを試す場合は、上記のアプローチの方がおそらく優れています。これを行わないでください。悪いアプローチです。 親コンポーネント: <テンプレート> <div id="父"> <div> 私は親コンポーネントです <son :analysisData="analysisData"> </息子> <p>インテリジェンス: {{ analysisData.wisdom }}</p> <p>膜法: {{ analysisData.magic }}</p> <p>攻撃: {{ analysisData.attack }}</p> <p>防御: {{ analysisData.defense }}</p> </div> </div> </テンプレート> <スクリプト> './son.vue' から son をインポートします。 エクスポートデフォルト{ データ: 関数 () { 戻る { 分析データ: 知恵: 90, 魔法: 160, 攻撃力: 100, 防御力: 80 } } }, コンポーネント: 息子:息子 } } </スクリプト> <スタイルスコープ> #父 div { パディング: 10px; マージン: 10px; 境界線: 1px の灰色 オーバーフロー: 非表示; } </スタイル> サブコンポーネント: <テンプレート> <div> <p>私はサブコンポーネントです</p> <p>インテリジェンス: {{ analysisData.wisdom }}</p> <p>膜法: {{ analysisData.magic }}</p> <p>攻撃: {{ analysisData.attack }}</p> <p>防御: {{ analysisData.defense }}</p> <button @click="increment ('wisdom')">知性を高める</button> <button @click="increment ('magic')">膜を増やす方法</button> <button @click="increment ('attack')">攻撃力を上げる</button> <button @click="increment ('defense')">防御力を上げる</button> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ 小道具: { 分析データ: オブジェクト }, メソッド: { 増分(データ名) { obj = this.analysisData とします。 obj[データ名] += 1 } } } </スクリプト> <!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します --> <スタイルスコープ> ボタン { float: 左 } </スタイル> 以上が、Vue における親子コンポーネント通信の詳細と、sync を使用して親子コンポーネントのデータを同期する方法です。Vue の詳細については、123WORDPRESS.COM の他の関連記事にも注目してください。 以下もご興味があるかもしれません:
|
<<: Mysql データベース ストアド プロシージャの基本構文の説明
MySQL自体は再帰構文をサポートしていませんが、自己接続を通じていくつかの単純な再帰を実現できます...
目次序文1. 再帰コンポーネント2. 右クリックメニューコンポーネント要約する序文今日、プロジェクト...
1. はじめにこれまで、テキストの特定の部分を強調したい場合、通常は太字にしたり明るい色を使用したり...
CSS プロパティのブラウザ互換性をまとめる必要があるのはなぜですか?使用する際は、Can I U...
1. インストール1. ダウンロードMySQLをダウンロードするには、MySQL公式サイトhttp:...
<br />以下は開発中に遭遇した問題と、そこから得た経験です。デバッグに時間がかかりま...
HTML の img タグで画像の中心を表示する方法は、現在 3 つあります。ここで記録しておきま...
詳細な手順は次のとおりです。 1. ディスク容量を確認します。 [root@localhost バッ...
今日は春節の金貨の赤い封筒のアクティビティを作りました。なかなか良い出来だと思います。皆さんと共有し...
#docker 検索#docker プルポーター1. イメージを取得した後、中国語パッケージをダウン...
これまでのブログ投稿では、HTML 5 ではあまり使われていないが注目すべき API やヒントに焦点...
目次1. vuexとは何か2. インストールと導入3. vuexの使用4. プロセスの紹介5. 突然...
1. nginxの動的と静的の分離の簡単な設定web1は静的サーバー、web2は動的サーバー、nod...
目次概要1. フックの呼び出し順序2. onChangesフック3. 変更検出メカニズムとDoChe...
1. コントロールパネルで、MySQLのすべてのコンポーネントをアンインストールします。コントロール...