ホームページ > 記事 > ウェブフロントエンド > vue での配列変更検出の問題
今回は、Vue での配列変更検出の問題について説明します。Vue での配列変更検出の 注意事項 は何ですか?実際のケースを見てみましょう。 りー
ここでの実装目的は非常に明確です。クリックしたときに li が存在するかどうかを検出したいと考えています。もちろん存在しないので、値を 1 に設定します。もう一度クリックすると、数値が累積されます。 しかし、発生する問題は、クリックした後、ビュー レイヤーで数値が更新されず、コンソールの印刷を通じて、データが実際に更新されたことが判明しますが、ビュー レイヤーがそれを時間内に検出しないことです。 そして、私が考えているのは、Vue は双方向のデータ バインディングを実装しているのに、モデル レイヤーが変更された後にビュー レイヤーで更新されないのはなぜでしょうか まず、これが配列の問題であるかどうかを検討し、次の例をテストしました: 例 2りぃ
この際、再度テストしてみたところ、ここのモデルレイヤーが変更された際に、タイムリーかつ効果的にビューレイヤーを更新できることが分かりました。 最も重要な文は、--- オブジェクトが応答性の場合、作成後にプロパティ も応答性であることを確認し、ビューの更新をトリガーすることです。このメソッドは主に、Vue が属性を検出できないという制限を回避するために使用されます。追加した。 。
では、どのような状況で Vue が属性が追加されたかを検出できない可能性があるのでしょうか?参考リンクによると、ドキュメント内で優れた説明が記載されています --- 詳細な反応原理 まず、Vue がデータの双方向バインディングをどのように実装するかを理解する必要があります。 通常のJavaScript オブジェクトを Vue インスタンスの data オプションに渡すと、Vue はこのオブジェクトのすべてのプロパティを反復処理して使用します。 Object.defineProperty は、これらすべてのプロパティをゲッター/セッターに変換します。 Object.defineProperty はのみです ES5 は機能をサポートしていますが、シム機能はサポートしていません。そのため、Vue は IE8 以前のブラウザをサポートしていません。
知識の補足: アクセサー プロパティにはデータ値は含まれません。アクセサー プロパティには、ゲッター関数とセッター関数のペアが含まれます (これら 2 つの関数は必須ではありません)。アクセサー プロパティが読み取られると、ゲッター関数が呼び出され、有効な値を返します。アクセサー プロパティが書き込まれると、セッター関数が呼び出され、新しい値が渡されます。この関数は、次の方法を決定します。データを処理します。 アクセサー プロパティは直接定義できず、Object.defineProperty() を使用して定義する必要があります。 以下に例を示します:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script> <style> li:hover { cursor: pointer; } </style> </head> <body> <p class="wrap"> <ul> <li v-for="item,index in items" v-on:click="handle(index)"> <span>{{item.name}}</span> <span>{{numbers[index]}}</span> </li> </ul> </p> <script> var vm = new Vue({ el: ".wrap", data: { numbers: [], items: [ {name: 'jjj'}, {name: 'kkk'}, {name: 'lll'}, ] }, methods: { handle: function (index) { // WHY: 更新数据,view层未渲染,但通过console这个数组可以发现数据确实更新了 if (typeof(this.numbers[index]) === "undefined" ) { this.numbers[index] = 1; } else { this.numbers[index]++; } } } }); </script> </body> </html>この例は、アクセサーのプロパティをよく理解するのに役立ちます。 したがって、オブジェクトのアクセサー属性値が変更されると (前述のように、Vue は属性をアクセサー属性に変換します)、set 関数が呼び出され、Vue はこの set 関数を通じて変更を追跡し、関連する関数を呼び出すことができます。をクリックしてビューを更新します。 各コンポーネント インスタンスには、対応するウォッチャー インスタンス オブジェクトがあり、コンポーネントのレンダリング プロセス中にプロパティが依存関係として記録され、後で依存関係のセッターが呼び出されるときに、ウォッチャーに再計算が通知され、その関連コンポーネントが更新されます。つまり、レンダリング プロセス中に、オブジェクト属性のゲッター関数が呼び出され、依存関係の後にオブジェクト属性が変更された場合に、ゲッター関数が水オブジェクトにそれを依存関係として宣言するように通知します。が呼び出されてウォッチャーに通知され、ウォッチャーはコンポーネントを再レンダリングして更新を完了します。 わかりました!原理がわかったので、前の配列の問題が発生した理由をさらに理解できるようになりました。
変更検出の問題
最新の JavaScript ブラウザの制限により、実際には主に Object.observe() になります。 メソッドのサポートが不十分で、Vue はオブジェクトの追加や削除を検出できません。ただし、Vue はインスタンスの初期化時にプロパティに対してセッター/ゲッター変換プロセスを実行するため、Vue がプロパティを変換するには、プロパティが最初からオブジェクト上に存在する必要があります。所以对于前面的例子就不能理解了 --- 数组中index都可以看做是属性,当我们添加属性并赋值时,Vue并不能检测到对象中属性的添加或者删除,但是其的确是添加或删除了,故我们可以通过console看到变化,所以就没有办法做到响应式; 而在第二个例子中,我们是在已有的属性的基础上进行修改的,这些属性是在最开始就被Vue初始化实例时执行了setter/getter的转化过程,所以说他们的修改是有效的,model的数据可以实时的在view层中得到相应。
补充知识: 什么是 Object.observe() ?
在介绍之前,不得不残忍的说,尽管这个方法可以在某些浏览器上运行,但事实是这个方法已经废弃!
概述: 此方法用于异步地监视一个对象的修改。当对象的属性被修改时,方法的回调函数会提供一个有序的修改流,然而这个接口已经从各大浏览器移除,可以使用通用的proxy 对象。
方法:
Object.observe(obj, callback[, acceptList])
其中obj就是被监控的对象, callback是一个回调函数,其中的参数包括changes和acceptList,
changes一个数组,其中包含的每一个对象代表一个修改行为。每个修改行为的对象包含:
name: 被修改的属性名称。
acceptList在给定对象上给定回调中要监视的变化类型列表。如果省略, ["add", "update", "delete", "reconfigure", "setPrototype", "preventExtensions"] 将会被使用。
var obj = { foo: 0, bar: 1 }; Object.observe(obj, function(changes) { console.log(changes); }); obj.baz = 2; // [{name: 'baz', object: <obj>, type: 'add'}] obj.foo = 'hello'; // [{name: 'foo', object: <obj>, type: 'update', oldValue: 0}] delete obj.baz; // [{name: 'baz', object: <obj>, type: 'delete', oldValue: 2}]
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がvue での配列変更検出の問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。