状況によっては、プレーンオブジェクトが最適な選択ではありません。 Map
オブジェクトをv-for
でレンダリングしようとしましたが、 Vue
は現在それをサポートしていないようです。 (これは、フォーラムのヘルプスレッドで作成した投稿です。)
Vue
がv-for
for ... of
構文を提供して、 Map
やSet
などのデータ型を反復処理できることを願っています。
例えば:
const map = new Map();
map.set('key1', 'val1');
map.set('key2', 'val2');
次のようにしてmap
をレンダリングできます。
<ul>
<li v-for="[key, val] of map">{{key}} - {{val}}</li>
</ul>
https://github.com/vuejs/vue/issues/1319の複製
@wenLiangcan 、次のようなものを使用できます:
<ul>
<li v-for="[key, val] of get(map)">{{key}} - {{val}}</li>
</ul>
ここで、 get()
は関数です。
はは! 同様の問題は常に開かれており、人々は実装を正当化できないと主張しています。人々はそれを使いたがっています。それは正当化の1つです。 また、ユースケースを非常によく正当化し、マップの順序に関してはes6仕様を参照するものを見つけました->まだ閉じています。
機能を使用したい人は、それだけでそのような機能の必要性を正当化できる議論ではなく、そのような機能を追加することのコストと利点(どのような問題が解決されているか)を比較検討する必要があります
うん、それでも問題を解決するために人々が使用する議論はまだ有効ではないか、少なくともすべてのユースケースに対して有効ではありません。たとえば、前述のように彼のユースケースを正当化したエリペンの例
特定の問題について話し合いたい場合は、それにリンクしてください。
さらに、この機能の問題は未解決です。 同じリクエストに対して複数の問題を開いておくのは意味がありません。
ループ内のイテレータを反復処理できることが重要です。 それは明白に思えます。 それは言語の基本的な特徴です。
それをサポートする理由は次のとおりです。
1)イテレータ、マップ、およびセットはすべて有効なES6です。 それらをサポートすることを拒否することは、ES5に自分自身を制限することを意味します。これは、時間の経過とともにますます正当化されなくなる決定です。
2)マップとセットに内部データが保存されているアプリケーションを構築しています。 UIで利用できるようにする代わりに、2つの間でデータを手動で同期するか、ボイラープレートを作成してテンプレートにインポートし、データが必要なときに変換を行う必要があります。 これはまさにVueが避けることを意図していることです。
#1319は閉鎖されているので、ここで現在の決定を繰り返す価値があります。 つまり、この機能は(観測メカニズムレベルで)実装するのは簡単ではないため、ユースケースを正当化することではなく、作業量とトレードオフについてです。
この機能も本当にありがたいです。 一方、ES6データ型の監視がひどくハッキーになったり、パフォーマンスやその他の品質が低下したりする場合、現在Vueでマップとセットを使用していない人はこの変更を理解しない可能性があります。
計算された関数内でArray.from()を使用することは、今のところあなたの親友である必要があると思います。 :残念だった:
そのための解決策はありますか?
小さな更新です。これは、Vueが「レガシー」ブラウザを削除し、反応性のためにset
/ get
ではなくProxy
Evergreenブラウザに移行する場合に発生します。
@ alexsandro-xpt、 Array.from(yourDataSet)
を返す計算関数を使用するだけです。
@nickmessing Mapを試してみましたが、機能しません。
計算された配列の長さの値は常に0です。
Array.from
は、反応性がないため、おそらくあなたが望む解決策ではありません( yourDataSet
への変更はVueに伝播されません)。
前述のように、セットとマップはVueでは監視できません。 これらをv-for
で使用するか、計算されたプロパティ、メソッド、ウォッチャー、テンプレート式などで使用するには、この構造のシリアル化可能なレプリカを作成し、Vueに公開する必要があります。 Setが更新されたという情報をVueに提供するために単純なカウンターを使用する単純な例を次に示します。
data() {
mySetChangeTracker: 1,
mySet: new Set(),
},
computed: {
mySetAsList() {
// By using `mySetChangeTracker` we tell Vue that this property depends on it,
// so it gets re-evaluated whenever `mySetChangeTracker` changes
return this.mySetChangeTracker && Array.from(this.mySet);
},
},
methods: {
add(item) {
this.mySet.add(item);
// Trigger Vue updates
this.mySetChangeTracker += 1;
}
}
これは、観察不可能なデータをリアクティブにするための、ちょっとハッキーですが100%機能する方法を示しています。 それでも、実際のケースでは、セット/マップのシリアル化されたバージョンになりました(たとえば、セット/マップの変更されたバージョンをローカルストレージに保存して、とにかくシリアル化する必要があります)ので、人工的なカウンター/ハックは含まれていませんでした。
私は個人的にこれが問題の公正な解決策だと思いますが、それは確かにいくつかの公式文書に値します—そうでなければ、これをVue内部を扱う非ハックな方法として正当化することは不可能です。
@アレックス・サンドロ・ロボ・シウバ-XPTは、申し訳ありませんが、私は、間違っていた@incaは、他のハックソリューションが使用されると述べたとしてハックになります計算$forceUpdate
する方法で、ここでの例ですフィドル
@nickmessingと@incaに感謝します、これは私のnew Map()
うまくいきます!!
現在、「マップ」に対して「v-for」を実行すると、v-forは空の配列を受け取ったかのように動作します。
マップとセットをサポートするかどうか/どのようにサポートするかについての広範な議論の結果に関係なく、Vueが単に「マップとセットはまだサポートされていません-https:// githubを参照してください」と警告した場合、多くの人がデバッグ時間を大幅に節約でき
うん、この機能のグーグル検索は私をこのチケットに連れて行った(Vue.setとのいくつかの厄介な取り違えの後)
👍これはv-forドキュメントにあるはずです!
本当に、vにあるべきです-ドキュメントのために!
/ cc @chrisvfritz v-for
(APIとリストレンダリングセクションの両方)のドキュメントに、これらのタイプのサポートに関するメモを追加してみましょう。2.5でもそれらを見ていきます。
@ yyx990803コンソールの警告がこれに適しているのではないかと思います。これにより、すぐに何が問題になっているのかが
また、ドキュメントでは、サポートするタイプ、 Map
とSet
含まれていないことについても非常に明確にしています。 すべての反復可能オブジェクトがv-for
で機能することを_期待_する理由についての議論は確かにわかりますが、現在、読者に期待する理由はないと思います。
Set
サポートを追加することに反対する議論はよくわかりません。
Set
自体はきれいにポリフィルすることができ、何かが足りない場合を除いて、配列に反応性を追加するためのVueのアプローチは非常に簡単にセットに拡張できるようです。 .add()
、 .clear()
、および.delete()
をラップするだけで済みます。
私の最善の推測(間違っている場合は訂正/申し訳ありません):最も難しい部分は、反復可能を受け入れるSet
コンストラクターをラップすることです。 一般的な形式では、参照可能な状態(例としてジェネレータベースのイテレータを考えてください)のない単なる関数(つまりnext
)であるため、イテレータをどのように監視可能にすることができるかわかりません。
コンストラクターをラップする必要があるのはなぜですか? 既存のセットをVueに渡しませんか?
仕様によるとSet
コンストラクターはイテレーター全体を即座に実行し、イテレーターによって返される一意のアイテムの浅いコピーを効果的に保持します。 Set
インスタンスを取得したら、それがイテレータから作成されたかどうかは関係ありません。
この点で、イテレータから作成されたSet
は、Vueがすでにサポートしているイテレータから( Array.from()
を介して)作成された配列と同じである必要があります。
不変のマップ/セット/任意のデータ構造を使用して、それらとの反応性を許可することができますが、それは単にチャンク参照全体が変更されるためです。 レンダリング関数または計算された生成された配列を介してそれらをレンダリングできます(配列の作成をスキップするため、早い方がパフォーマンスが向上します。)。 ただし、変更可能なデータ構造は、特定の変更を手動でVueに通知する方法を見つけない限り、そうではありません。これは、独自のソリューションを自作するだけです。
それは良くないね。 あなたはそれをすることはできません
@wenLiangcan
var map = new Map()
map.set('key1','Test1')
map.set('key2','Test2')
<div class="file-size">{{value}}</div>
</div>
いいえ、ページに表示されません
これのサポートに熱心です:)
私も
サポートを追加する将来の計画はありますか? Vueがマップとセットをサポートできなかった技術的な理由はありますか?
プレーンオブジェクトのVue.setメソッドに関する現在の問題は、プロパティがオブジェクトに追加されたときに、非常に多くのサブスクライバーをトリガーすることです。 実際には、すべてのプロパティのすべてのサブスクライバーは、1つのプロパティのみが追加されたときにトリガーされます。
コレクションのようなマップに100分の1のキーが含まれていると、ビューのパフォーマンスに大きな影響があります。 たとえば、私のプロジェクトでは、Vue.set操作を使用して1つの要素がマップに追加されると、何千ものサブスクライバーがトリガーされます。
Vue.set(state.items, itemId, item); // where items is a plain object.
Vue.jsコードを詳しく調べると、問題の原因がわかります。 トリガーされる依存関係はオブジェクトの依存関係です。つまり、オブジェクトにキーごとに1つのプロパティがある場合、1つのキーを追加するだけで、すべてのキーのすべての依存関係がトリガーされます。
したがって、プレーンオブジェクトを使用してマップを模倣することは適切な解決策とは見なされません。したがって、vueでマップをサポートすることは、アイテムの大規模なコレクションに対して歓迎されます。
将来の計画について、そしておそらくネイティブのMap/Set
サポートについてのニュースはありますか?
この記事では、2.6での今後のサポートについて詳しく説明しますが、公式のロードマップには、私が見ることができるものからは何もありません。
https://medium.com/@alberto.park/the -status-of-javascript-libraries-frameworks-2018-beyond-3a5a7cae7513
「コアの現在の最新版は2.5.xです。次のマイナーリリース(v2.6)は、ネイティブESMインポート、改善された非同期エラー処理、「v-for」ディレクティブのイテレーターなどをサポートします。」
彼らがその情報をどこから入手したのかわからないのですか?
Set
データオブジェクトに対するVueの動作をデバッグしているときに、この問題が見つかりました。 :考え:
このロードマップについて疑問に思っていた私のような人々のために、Evan Youはこのビデオで、マップとセットのサポートは2.6に到着する可能性が高いと述べていますが、それは5月でした。
@ yyx990803特に近い将来にサポートを追加することを検討している場合は、トラッカーのこの問題がクローズとしてマークされているのは残念です。 この機能の進捗状況はどこで確認できますか? どこかに別の問題がありますか?
議論のために疑問に思っているだけで、私は間違っているかもしれませんが、 Mutation Methodsを使用して配列の突然変異を追跡できるので、オブジェクトの配列を追跡して論理的に完全にすることはできませんか? Mapに実装されているすべての同じ機能を取得することはできませんが、特に_やlodashなどを使用している場合は、必要な機能に簡単に対処できます。
悲しいですが、チームがこれを追加するまで、別のデータ構造を使用する必要があるかもしれません
データ構造にマップを使用することをチャイムしたいのですが、ファーストパーティのサポートがないため、マップを使用しないことにしました。
これはvue.jsv3.0で計画されています。
比較: https :
これは現在Vue3でサポートされていますか(つまり、リアクティブMap
とSet
)?
最も参考になるコメント
ループ内のイテレータを反復処理できることが重要です。 それは明白に思えます。 それは言語の基本的な特徴です。
それをサポートする理由は次のとおりです。
1)イテレータ、マップ、およびセットはすべて有効なES6です。 それらをサポートすることを拒否することは、ES5に自分自身を制限することを意味します。これは、時間の経過とともにますます正当化されなくなる決定です。
2)マップとセットに内部データが保存されているアプリケーションを構築しています。 UIで利用できるようにする代わりに、2つの間でデータを手動で同期するか、ボイラープレートを作成してテンプレートにインポートし、データが必要なときに変換を行う必要があります。 これはまさにVueが避けることを意図していることです。