テキスト
コンポーネントのVueの間のデータ「交流」の異なるシナリオについて話します
Vueの公式文書は非常に詳細であると言うことができます。私の意見では、これと他のフレームワークやその他の文書は、より多くの方法については、同じ反応もつながった、「現場で」「方法論」とはないこと:私たちは、ドキュメントを何度も読み終え、と書いた後、コードまたは助けるが、我々はいくつかの知識ポイントのでの使用シーンを知らないので、多くの混乱がある感じることができません。この私はVueのを達成するために、異なるシナリオの下でのコンポーネント間のデータの「交流」を探るこの記事を書くの目的であります
父と息子のコンポーネント間のデータ交換
コンポーネント間の息子のデータ通信は、2つのタイプに分けることができます。
1.データは、親コンポーネントサブアセンブリに移し
2.データは、親サブアセンブリの構成要素に伝達されます。
親コンポーネントは、サブアセンブリ--propsにデータを渡します
これは、最も一般的なシナリオであるコンポーネントのデータ通信である:あなたは親コンポーネントのマスター・データ・ソースを聞かせて、その後の使用のためのサブコンポーネント、サブアセンブリに渡されます
多くは、これは非常に単純であることを言うだろう!まあ小道具付き!はい、このために、私はそれが主な内容ではないと言いたいが、我々はまだ簡単なコードでオーバー行きます:
親コンポーネント
<テンプレート> <DIV ID = "父"> {{ 'I親要素'}} <息子:テキスト= "テキスト"> </息子> </ div> </テンプレート> <スクリプト> からインポート息子。 /son.vue ' エクスポートデフォルト{ データ:関数(){ リターン{ テキスト:'親コンポーネントから送信されたデータ' } }、 コンポーネント:{ ソン:息子 } } </ SCRIPT> <スタイルスコープ> </スタイル>
サブコンポーネント:
<テンプレート> の<div> {{ '我是子组件、我接收了' +テキスト}} </ DIV> </テンプレート> <スクリプト> 輸出デフォルト{ 小道具:{ テキスト:{タイプ:文字列、デフォルト: '' } } } </ SCRIPT> <! - -追加のみ、このコンポーネントにCSSを制限するための属性"スコープ"> <スタイルはスコープ> </スタイル>
デモ:
そこにこのデモでは、私たちが「親コンポーネントからのデータを」持っていることは、サブアセンブリに小道具を通過した文字列です
私たちは、親要素のサブアセンブリ内のデータを変更したい場合は、コンポーネントのデータ変更の親関数の親コンポーネントで定義され、その後、小道具サブアセンブリを使用して関数に渡され、サブアセンブリは、適切な時に関数を呼び出すことができます - 親コンポーネントを変更するため、サブアセンブリ効果のデータを再生します
サブアセンブリの構成部品は、親にデータを渡します
サブアセンブリは、親要素の道にデータを渡します。コールバックパラメータの受け渡し
親コンポーネント:
<テンプレート> <DIV ID = "父"> {{ '我是父组件、名称是' + componentNameでは}} <息子:changeComponentName = "changeComponentName"> </息子> </ div> </テンプレート> <SCRIPT> インポート息子から'./son.vue' エクスポートデフォルト{ データ:関数(){ リターン{ コンポーネント名: '组件A' } }、 メソッド:{ changeComponentName:関数(newComponentName){ this.componentName = newComponentName } }、 成分: { 息子:息子 } } </ SCRIPT> <スタイルは、スコープ> #father DIV { パディング:10pxの。 マージン:10pxの; 国境:1pxの灰色の固体。 } </スタイル>
サブコンポーネント:
<テンプレート> の<div> <p型> Iサブコンポーネント:ボタン</ p型> <= @clickボタン"()=> changeComponentName(newComponentName)"> 次のように修正された親コンポーネントの名前:鵬ベイ・コンポーネントを < /ボタン> </ div> </テンプレート> <SCRIPT> エクスポートデフォルト{ データ:関数(){ リターン{ newComponentName: '鵬ベイアセンブリ' } }、 小道具:{ changeComponentName:{ タイプ:機能、 デフォルト:( )=> {} } } } </ SCRIPT> <! - > -追加は、このコンポーネントのみにCSSを制限するための属性"スコープ" <スタイル>スコープ </スタイル>
デモ:
前クリックしてください。
クリックしてください:
グラフィック:
「A」から親コンポーネントの名前は「鵬湾コンポーネント」に変更されたサブコンポーネント(ボタン)をクリックします
我々は、サブアセンブリの構成要素に親から機能(changeComponentName)を通過しました。サブアセンブリと、この関数が呼び出されたときに、そのようなパラメータとして、この関数にサブアセンブリ(newComponentName)内のデータを渡し、関数(changeComponentName)が送信されたパラメータを取得することができる親コンポーネントサブアセンブリに定義されインクルード
あまりにも恥ずかしい[PS]名前
カスタムイベント:サブアセンブリは、親アセンブリの道へデータを渡します
親コンポーネント:
<template> <div id="father"> <div> {{ '我是父组件,我的名称是:' + fatherComponentName }} <son v-on:changeComponentName = "changeComponentName"></son> </div> </div> </template> <script> import son from './son.vue' export default { data: function () { return { fatherComponentName: 'A组件' } }, methods: { changeComponentName: function (componentName) { this.fatherComponentName = componentName } }, components: { son: son } } </script> <style scoped> #father div{ padding: 10px; margin: 10px; border:1px solid grey; } </style>
子组件:
<template> <div> <p>我是子组件:一个按钮</p> <button @click="clickCallback"> 修改父组件的名称为:彭湖湾的组件 </button> </div> </template> <script> export default { data: function () { return { fatherComponentName: '彭湖湾的组件' } }, methods: { clickCallback: function () { this.$emit('changeComponentName', this.fatherComponentName) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
demo:
点击前:
点击后:
图解:
通过$emit(event, [...参数]),所有的参数将被传递给监听器回调,也就是我们在父组件中定义的changeComponentName方法,从而实现从子组件中给父组件传参
兄弟组件间的数据交流(有共同父组件的兄弟组件)
父组件:
<template> <div id="father"> <div> {{ '我是父组件:father' }} <eldest-son :text = "text"></eldest-son> <youngest-son :changeText="changeText"></youngest-son> </div> </div> </template> <script> import eldestSon from './eldestSon.vue' import youngestSon from './youngestSon.vue' export default { data: function () { return { text: '我是一行文本' } }, methods: { changeText: function () { this.text = '我是经过改动的一行文本' } }, components: { eldestSon: eldestSon, youngestSon: youngestSon } } </script> <style> #father div{ border: 1px solid grey; padding: 10px; margin: 10px; } </style>
兄弟组件1:
<template> <div> <p>我是兄弟组件:eldestSon</p> <p>我有一个可变数据text:{{ text }}</p> </div> </template> <script> export default { props: { text: { type: String, default: '' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
兄弟组件2:
<template> <div> <p>我是兄弟组件:youngestSon</p> <button @click="changeText">更改eldestSon兄弟组件中的文本</button> </div> </template> <script> export default { props: { changeText: { type: Function, default: () => {} } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
点击前:
点击后:
图解:
如果两个兄弟组件间存在这种数据关系的话,我们可以尝试寻找其共同的父组件,使数据和相关方法“提升”到父组件内部,并向下传给两个子组件
这样,其中一个子组件取得了数据,另外一个子组件取得了改变数据的方法,便可以实现上述的数据沟通
【注意】这种场景存在局限性,它要求两个组件有共同父组件。对于这种场景之外的处理方法,请看下文
グローバルコンポーネント間のデータ交換--Vuex
私は、コンポーネント間のデータ通信を処理する方法を渡す小道具または関数パラメータに適用される多くのシーン上記。しかし、内部のわずかに大きいアプリケーションでは、彼らは常に私たちに多くの問題をもたらしています
例えば:
小道具を介してサブアセンブリに親コンポーネントから1のデータ転送
親子関係の直接の構成要素については、データ・フローは、非常に明確かつシンプルですが、中に大規模なアプリケーション、私たちの多くアップし、非常に煩雑で困難な我々のコードにつながるネストされたコンポーネント、ダウンを維持するとき、
兄弟コンポーネントの場合2.データ転送モードを渡す関数パラメータは何もできない、共通の親要素を持っていない、に導入Vueのドキュメント、あなたは$関数ベースの「イベントバス」通信に放出し、$にデータを渡すことができますが、それは、より大規模なアプリケーションに対応できません
この時間Vuexは、グローバルなコンポーネント間のデータ交換を実現するために最適なソリューションとなりました
Vuexは、すべての状態の上部層を含む単一のデータソース(状態)を有しています
1.すべてのコンポーネントは、単一のデータソースデータ内で使用することができます
2.すべてのコンポーネントは、データ配信動作(アクション)のこの単一のソースで変更することができます
データ・ストリームの通信を実現するために「回り道をたくさん取る」ことになって、突然最短ショートカットを見つけました
デカップリング層データとモデルレイヤを表示
第3のセクション(Vuex)で処理部1とデータ処理におけるデータ(ヴュ)、データの多くの場合に2つの異なるタイプ、前者はビュー層に属し、UIの単純な表示を担当して、モデル大部分のデータ取得の後端から注入層。
提案:
ビュー層を構築するための責任のコードの一部1.Vue
モデル層を構築するための責任のコードの一部2.Vuex
(Vuex外部上記Vueのフレームワークを参照してください)
Vuex Vueの内部書き込まれ、表示層とモデル層のデカップリングを達成するために、両者を分離し、フロントエンドコードの保守性を改善しようと書かれている部分に最終的に決定されたコードに基づいて上記2点で拡張性