vue.js で props がパラメータを渡す方法の詳細な説明

亚连
リリース: 2018-06-21 14:33:40
オリジナル
2234 人が閲覧しました

vue.js でパラメータを渡す props の関連知識と問題解決方法を詳細に分析します。必要な友人は参考にしてください。

この記事では、デモの例を使用して、パラメーターを渡す props の使用法と発生した問題の解決策の詳細な分析を提供します。以下はその全内容です。

少し前に、vue を使用してバックエンド管理システムを構築しました。このシステムでは、各ページに情報を表示するためのテーブルが必要です。当然のことながら、再利用の目的を達成するために、テーブルを抽出してパブリック コンポーネントにし、レンダリングのために別のページからデータを渡すことを考えました。

デモアドレス

1. 問題発見

親コンポーネントでは、テーブルコンポーネントに渡す必要があるデータには、テーブルのコンテンツデータ、tableData、テーブルのページデータが含まれます。

<p>
 <my-table :table-data="tableData" :page-info="pageInfo" id="myTable"></my-table>
</p>
ログイン後にコピー

ここで、tableData は Array オブジェクトで、テーブルに表示する必要があるすべてのデータ オブジェクトで構成される配列です。また、pageInfo はテーブル ページ情報を含む Object オブジェクトです。次のように親コンポーネントの 2 つのデータ ペアを

tableData:[],
pageInfo: {
 current: 1, // 当前是第几页
 total: 100, // 数据对象的总数
 size: 20 // 每页显示的数量
}
ログイン後にコピー

の形式で初期化します。公式ドキュメントの指示によると、prop は一方向バインドされており、子コンポーネント内で prop を変更すべきではありません。 prop のデータを変更したい理由は、主に prop が初期値として渡された後、サブコンポーネントがそれをローカル データとして使用したいためです。この状況に対する公式ステートメントは、ローカル変数を定義し、それを prop の値で初期化することです:

props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}
ログイン後にコピー
ログイン後にコピー

その後、公式ドキュメントによると、親コンポーネントが更新されるたびに、子コンポーネントのすべての props が次のように更新されます。最新の値。 tableData と pageInfo の情報は API を通じてサーバーから非同期で取得されます:

{
 error: 0,
 msg: "调用成功.",
 data: {
  restrictioninfo: [...],
  total: 42
 }
}
ログイン後にコピー

したがって、データを取得するときに、親コンポーネントは子コンポーネントに渡される値を変更する必要があります:

me.tableData = Json.data.restrictioninfo;
me.pageInfo.total = Json.data.total;
ログイン後にコピー

論理的に言えば、子コンポーネントはサーバーから返された値に更新される必要がありますが、サブコンポーネント ページの総数は更新されていますが、テーブル データは初期化中に空の配列のままです。 (黒い疑問符???)


2. 割り当てとバインディング

まず、データのどこに問題があるのか​​を特定する必要があるため、問題を特定するためのデモを作成しました。

まず、親コンポーネントと子コンポーネントの各要素の初期値を確認します:

次に、親コンポーネントの配列への参照のみが変更されると、プロパティの配列が変更されていることがわかります。それに応じて子コンポーネントが変更され、子コンポーネントのバインディングもそれに応じて変更されていません

したがって、問題はこのステップにあることがわかります

props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}
ログイン後にコピー
ログイン後にコピー

そして、問題の根本を突き止めるには、 vue ドキュメントで詳細な応答性の原則を理解する必要があります。

"Vue インスタンスのデータ オプションで、Vue はこのオブジェクトのすべてのプロパティをトラバースし、Object.defineProperty を使用してこれらすべてのプロパティをゲッター/セッターに変換します。", "各コンポーネント インスタンスには、対応するウォッチャー インスタンス オブジェクトがあります。 、コンポーネントのレンダリング中にプロパティを依存関係として記録し、依存関係のセッターが呼び出されたときに再計算するようにウォッチャーに通知し、関連するコンポーネントが更新されるようにします。「ドキュメントには多くのことが書かれています。簡単に理解すると、Vue は双方向にバインドされます。」データ オプションの vm.$data.a と DOM の vm.a、つまり、一方が変更されると、他方も変更されます。 Vue のソース コードでは、defineReactive$$1 関数によって実装されています:

ただし、サブセクションでは、主に Object.defineProperty の get メソッドと set メソッドを使用して双方向バインディングを実現します。サブコンポーネントでは、pros データとサブコンポーネントの $data が次の方法で接続されています:

tData: this.tableData
ログイン後にコピー

Vue ソース コードをクエリすると、this.tableData と tData の間には割り当てのみがあることがわかります。 "= 関係

上記の initData 関数はコンポーネントのビルド時に実行されるため、作成中に 1 回だけ実行されます。公式ドキュメントに「初期値として渡す」と書かれているのは、一度しか実行されないためです。コンポーネントが構築されるとき、this.tableData と tData の間には関係はありません。一方を変更しても、もう一方は変更されません。もちろん、この記述は正確ではありません。なぜなら、上記では、親コンポーネントによって渡された合計が動的に変更され、子コンポーネントも「同時に」変更されるからです。何が起こっているのでしょうか。 ?

3. 参照型によって引き起こされるアーティファクト

もちろん、この問題を解決するには、まだ公式ドキュメントから始める必要があります。文書にはそのようなヒントがあります:

这里就需要理解引用类型的概念,引用数据类型值指保存在堆内存中的对象。也就是,变量中保存的实际上的只是一个指针,这个指针指向内存中的另一个位置,该位置保存着对象。访问方式是按引用访问。例如一个js对象a,他在内存中的存储形式如下图所示:

var a = new Object();
ログイン後にコピー

当操作时,需要先从栈中读取内存地址,然后再延指针找到保存在堆内存中的值再操作。

a.name = &#39;xz&#39;;
ログイン後にコピー


引用类型变量赋值,本质上赋值的是存储在栈中的指针,将指针复制到栈中未新变量分配的空间中,而这个指针副本和原指针指向存储在堆中的同一个对象;赋值操作结束后,两个变量实际上将引用同一个对象。因此,在使用时,改变其中的一个变量的值,将影响另一个变量。

var b = a;
ログイン後にコピー


在了解了引用类型之后,我们在来看看上文提到的动态改变传入子组件前后内存中的情况:

me.tableData = Json.data.restrictioninfo;
me.pageInfo.total = Json.data.total;
========================================
props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}
ログイン後にコピー

首先对tableData的改变是改变了其引用的指针,而对pageInfo则改变了其中一个属性的值,因此动态改变前:

动态改变后:

这样就解释了为什么子组件页面的总数更新了,但table数据依然是初始化时的空数组。因为引用类型的存在,我们动态改变父组件传入的total,子组件也"随之"改变了。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在jQuery中如何实现点击DIV触发点击CheckBox

使用JS如何实现点击复选框修改显示状态

在Vue中标准的处理方法(详细教程)

以上がvue.js で props がパラメータを渡す方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート