最近、会社のプロジェクトでバグがあり、シナリオは次のとおりです。サブコンポーネントをトラバースするループとしてリストを使用し、リストの添え字のインデックスを持つキー値は、図のように、サブコンポーネントに渡されたprops属性としてリストの各項目。
サブコンポーネントでは、図のように、項目内の値がコンポーネントのデータプロパティを定義する判断基準として使用されます。
コンポーネントはこのようになります。
この時、バグが発生し、3番目のサブコンポーネントのスクリーニング後、1位になり、その後、isChange属性の判定基準として項目の値でデータ化し、isChange属性の最初のコンポーネントのスクリーニング前でも、isChangeのサブ1がtrue、isChangeのサブ3がfalse、isChangeのサブ3のスクリーニング後にtrueになります。フィルタリング後にisChangeが真になるとバグが成立します。
その後、問題を見つけるが、リストの配列は、スクリーニングによって変更されますが、サブコンポーネントに渡されたデータが正しいので、定義では、データ内のサブコンポーネントのデータは、受信データに依存している、右には変更されません、なぜ最初の3番目のコンポーネントの順序は、データ内のデータが変更されましたか?
なぜ3番目のコンポーネントの順序が最初のものになったときに、3番目のコンポーネントのデータが変更されたのですか? 理由を研究して、私はそれが変更された 仮想DOMの部分を計算し、ページ全体を再レンダリングすることなく、その部分のネイティブDOM操作を実行する差分アルゴリズムのゴーストであることがわかりました。
下図に示すように、更新されたサブコンポーネント3はサブコンポーネント1の位置に来て、そのキー値は0になるので、古いもの、つまりサブコンポーネント1の同じインデックスと比較されます。比較後、diffアルゴリズムはpropsが受け取ったアイテムのデータを変更するだけです。dataは戻り値を持つ関数であり、この操作はローカル更新のみで、コンポーネントを再読み込みしないので、data関数は再実行されず、同じ関数に従います。関数は再実行されず、元のインデックス 0 の data が返すデータに従うため、問題が発生します。
解決策:項目のidを探索のキー値として使用することで、問題は解決します。
Tips:開発の過程でv-forループの配列を使用する場合、私のような手間を省くためにindex添え字をキー値として使用することは避け、idなどのitemのユニークな属性をキー値として使用することをお勧めします。頑張れ~!