Vue: Mendukung lebih banyak tipe data koleksi di v-for

Dibuat pada 28 Feb 2016  ·  39Komentar  ·  Sumber: vuejs/vue

Pada beberapa situasi, objek polos bukanlah pilihan terbaik. Saya mencoba merender objek Map oleh v-for , tetapi tampaknya Vue tidak mendukungnya saat ini. (Inilah posting yang saya buat di utas Bantuan di forum.)

Semoga Vue dapat memberikan sintaks for ... of di v-for untuk beralih pada tipe data seperti Map dan Set .

Sebagai contoh:

const map = new Map();
map.set('key1', 'val1');
map.set('key2', 'val2');

dan kita dapat merender map dengan cara ini:

<ul>
    <li v-for="[key, val] of map">{{key}} - {{val}}</li>
</ul>
feature request

Komentar yang paling membantu

Sangat penting untuk dapat mengulangi iterator dalam loop. Itu terlihat jelas. Ini adalah fitur mendasar dari bahasa.

Alasan mendukungnya adalah:

1) Iterator, Peta, dan Set semuanya adalah ES6 yang valid. Menolak untuk mendukung mereka berarti membatasi diri Anda pada ES5, yang merupakan keputusan yang semakin lama semakin tidak dapat dibenarkan.
2) Saya sedang membangun aplikasi yang memiliki data internal yang disimpan di Maps dan Sets. Alih-alih membuatnya tersedia untuk UI, saya sekarang perlu menyinkronkan data di antara keduanya secara manual, atau menulis boilerplate dan mengimpornya ke template saya untuk melakukan konversi kapan pun data diperlukan. Inilah yang sebenarnya ingin dihindari oleh Vue.

Semua 39 komentar

Duplikat https://github.com/vuejs/vue/issues/1319

@wenLiangcan , Anda bisa menggunakan sesuatu seperti ini:

<ul>
    <li v-for="[key, val] of get(map)">{{key}} - {{val}}</li>
</ul>

di mana get() adalah fungsi Anda.

ha ha! masalah serupa terbuka sepanjang waktu dan dan orang-orang bersikeras bahwa mereka tidak dapat membenarkan implementasi dengan baik orang ingin menggunakannya itu satu pembenaran Saya juga dapat membuat daftar bazillion masalah tertutup yang menanyakan hal yang sama xD. Saya juga menemukan satu yang membenarkan kasus penggunaan dengan sangat baik dan mengacu pada spesifikasi es6 ketika datang ke urutan peta -> masih ditutup.

Orang yang ingin menggunakan fitur tidak, hanya dengan sendirinya, argumen yang dapat membenarkan perlunya memiliki fitur tersebut, perlu mempertimbangkan biaya dan manfaat (masalah apa yang sedang dipecahkan) dari menambahkan fitur tersebut

Yap tapi tetap saja argumen yang digunakan orang untuk menutup masalah masih belum valid atau setidaknya tidak valid untuk semua usecase misalnya contoh elipen yang membenarkan usecase-nya dengan sangat baik seperti yang saya sebutkan di atas

Jika Anda ingin membahas masalah tertentu, harap berikan tautannya.

Plus, masalah Fitur ini terbuka. Tidak masuk akal untuk membuka lebih dari satu masalah untuk permintaan yang sama.

Sangat penting untuk dapat mengulangi iterator dalam loop. Itu terlihat jelas. Ini adalah fitur mendasar dari bahasa.

Alasan mendukungnya adalah:

1) Iterator, Peta, dan Set semuanya adalah ES6 yang valid. Menolak untuk mendukung mereka berarti membatasi diri Anda pada ES5, yang merupakan keputusan yang semakin lama semakin tidak dapat dibenarkan.
2) Saya sedang membangun aplikasi yang memiliki data internal yang disimpan di Maps dan Sets. Alih-alih membuatnya tersedia untuk UI, saya sekarang perlu menyinkronkan data di antara keduanya secara manual, atau menulis boilerplate dan mengimpornya ke template saya untuk melakukan konversi kapan pun data diperlukan. Inilah yang sebenarnya ingin dihindari oleh Vue.

Karena #1319 ditutup, ada baiknya mengulangi keputusan saat ini di sini. Singkatnya, fitur ini tidak sepele untuk diterapkan (pada tingkat mekanisme pengamatan), jadi ini bukan tentang membenarkan kasus penggunaan, ini tentang jumlah pekerjaan dan pengorbanan.

Saya juga akan sangat menghargai fitur ini. Di sisi lain, jika mengamati tipe data ES6 menjadi sangat berbahaya atau, misalnya, mengganggu kinerja atau kualitas lainnya, maka orang yang saat ini tidak menggunakan Maps dan Sets dengan Vue mungkin tidak menghargai perubahan ini.

Saya kira menggunakan Array.from() di dalam fungsi yang dihitung harus menjadi teman terbaik Anda untuk saat ini. :kecewa:

Ada solusi untuk itu?

Pembaruan kecil, ini akan datang jika/ketika Vue memutuskan untuk menghapus browser "lama" dan akan pindah ke Evergreen dengan Proxy alih-alih set / get untuk reaktivitas.

@alexsandro-xpt, cukup gunakan fungsi yang dihitung yang mengembalikan Array.from(yourDataSet) .

@nickmessing saya coba dengan Map, tidak berhasil.
Nilai panjang array yang dihitung selalu 0.

Hanya Array.from mungkin bukan solusi yang Anda inginkan karena kurangnya reaktivitas (perubahan pada yourDataSet tidak akan disebarkan ke Vue).

Seperti yang disebutkan sebelumnya, Set dan Maps tidak dapat diamati oleh Vue. Untuk menggunakannya — baik dalam v-for , atau dalam properti terkomputasi, metode, pengamat, ekspresi templat, dll. — Anda perlu membuat replika bersambung dari struktur ini dan mengeksposnya ke Vue. Berikut adalah contoh naif yang menggunakan penghitung sederhana untuk memberikan informasi kepada Vue bahwa Set diperbarui:

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;
  }
}

Ini menggambarkan metode yang agak hacky tetapi 100% berfungsi untuk membuat data yang tidak dapat diamati menjadi reaktif. Namun, dalam kasus dunia nyata saya berakhir dengan versi serial dari Sets/Maps (misalnya Anda mungkin ingin menyimpan versi modifikasi dari set/maps di penyimpanan lokal dan dengan demikian membuat serial mereka), jadi tidak ada counter/hack buatan yang terlibat.

Saya pribadi berpikir ini adalah solusi yang adil untuk suatu masalah, tetapi itu pasti layak mendapatkan beberapa dokumentasi resmi - jika tidak, tidak mungkin untuk membenarkan ini sebagai cara non-retas dalam menangani internal Vue.

@alexsandro-xpt, maaf, saya salah, dihitung akan diretas seperti yang dikatakan peretasan lain akan menggunakan $forceUpdate dengan metode, inilah contoh biola

Terima kasih @nickmessing dan @inca , ini berfungsi dengan baik dengan new Map() !!

Saat ini ketika Anda melakukan "v-for" di atas "Peta", v-for bertindak seolah-olah telah menerima array kosong.

Terlepas dari hasil diskusi panjang tentang apakah/bagaimana mendukung Maps dan Sets, itu akan menghemat banyak waktu debugging orang jika Vue hanya memperingatkan "Maps dan Sets belum didukung -- lihat https://github .com/vuejs/vue/issues/2410 ".

Yup, pencarian Google untuk fitur ini membawa saya ke tiket ini (setelah beberapa kesalahan yang mengganggu dengan Vue.set)

👍 Ini harus ada di dokumentasi v-for!

Sungguh, harus di v-untuk dokumentasi!

/cc @chrisvfritz mari kita coba tambahkan catatan tentang dukungan untuk jenis ini di dokumen untuk v-for (baik API dan bagian daftar rendering) - Saya juga akan melihatnya di 2.5.

@ yyx990803 Saya ingin tahu apakah peringatan konsol akan lebih baik untuk ini, karena itu akan segera memberi tahu orang-orang apa yang salah, meniadakan kebutuhan untuk mencari solusi.

Kami juga sudah sangat eksplisit dalam dokumen tentang jenis yang kami _do_ dukung, Map dan Set tidak termasuk di antara mereka. Saya pasti bisa melihat argumen mengapa seseorang mungkin _hope_ semua iterables akan bekerja dengan v-for , tapi saya rasa saat ini kami tidak memberi pembaca alasan untuk mengharapkan mereka melakukannya.

Saya tidak cukup melihat argumen yang menentang penambahan dukungan untuk Set .

Set itu sendiri dapat di-polyfill dengan rapi, dan kecuali saya melewatkan sesuatu, sepertinya pendekatan Vue untuk menambahkan reaktivitas ke array dapat dengan mudah diperluas ke set. Kita hanya perlu membungkus .add() , .clear() , dan .delete() .

Tebakan terbaik saya (mohon koreksi/maaf jika saya salah): bagian tersulit adalah membungkus konstruktor Set , yang menerima iterable. Saya tidak melihat bagaimana iterable dapat dibuat dapat diamati, karena dalam bentuk umumnya itu hanya sebuah fungsi (yaitu next ) tanpa status yang dapat direferensikan (pikirkan iterator berbasis generator sebagai contoh).

Mengapa kita perlu membungkus konstruktor? Bukankah kita akan meneruskan Set yang sudah ada sebelumnya ke Vue?

Menurut spec , konstruktor Set segera menjalankan seluruh iterator, secara efektif mempertahankan salinan dangkal dari item unik yang dikembalikan oleh iterator. Setelah Anda mendapatkan instance Set , tidak masalah apakah itu dibuat dari iterator atau tidak.

Dalam hal ini, Set dibuat dari iterator seharusnya tidak berbeda dengan array yang dibuat dari iterator (melalui Array.from() ), yang sudah didukung oleh Vue.

Anda dapat menggunakan Peta/set/struktur data apa pun yang tidak dapat diubah dan memungkinkan reaktivitas dengannya, tetapi hanya karena seluruh referensi potongan berubah. Anda dapat merendernya melalui fungsi render atau array yang dihasilkan yang dihitung (yang sebelumnya lebih baik kinerjanya karena melewatkan pembuatan array..). Tetapi struktur data yang dapat berubah, tidak demikian kecuali jika Anda menemukan cara untuk memberi tahu Vue tentang perubahan tertentu secara manual, yang hanya akan menjadi solusi homebrewing Anda sendiri.

Itu tidak baik. Anda tidak bisa melakukannya

@wenLiangcan

var map = new Map()
  map.set('key1','Test1')
  map.set('key2','Test2')
        <div class="file-size">{{value}}</div>
 </div>

Tidak, itu tidak muncul di halaman

Tertarik untuk mendukung ini :)

gerakan mengungkap kekerasan seksual demi menghapuskannya

Ada rencana masa depan untuk menambahkan dukungan? Apakah ada alasan teknis Vue tidak dapat mendukung Map and Set?

Masalah saat ini dengan metode Vue.set pada objek biasa adalah bahwa metode tersebut memicu terlalu banyak pelanggan saat properti ditambahkan ke objek. Sebenarnya, semua pelanggan dari semua properti dipicu ketika hanya satu properti yang ditambahkan.

Performa tampilan sangat terpengaruh ketika koleksi seperti peta berisi seperseratus kunci. Misalnya, dalam proyek saya, ribuan pelanggan dipicu ketika satu elemen ditambahkan ke peta menggunakan operasi Vue.set:

Vue.set(state.items, itemId, item); // where items is a plain object.

Ketika saya melihat lebih dalam ke kode Vue.js, saya dapat melihat dari mana masalahnya berasal. Dependensi yang dipicu adalah milik objek, yang berarti bahwa jika objek memiliki satu properti untuk setiap kunci, maka semua dependensi dari semua kunci akan terpicu saat hanya menambahkan satu kunci.

Jadi menggunakan objek biasa untuk meniru peta tidak terlihat sebagai solusi yang tepat, dan oleh karena itu memiliki dukungan untuk peta di vue lebih dari diterima untuk koleksi besar item.

Apakah ada berita tentang rencana masa depan dan mungkin tentang dukungan asli Map/Set ?

Artikel ini merinci dukungan yang akan datang di 2.6 - tetapi tidak ada apa pun tentang itu di peta jalan resmi dari apa yang bisa saya lihat?

https://medium.com/@alberto.park/the -status-of-javascript-libraries-frameworks-2018-beyond-3a5a7cae7513

"Inti terbaru saat ini adalah 2.5.x. Rilis minor berikutnya (v2.6), akan mendukung impor ESM asli, penanganan kesalahan asinkron yang ditingkatkan, iterator pada arahan 'v-for' dan banyak lagi."

Tidak yakin dari mana mereka mendapatkan informasi itu?

Menemukan masalah ini saat sedang men-debug perilaku Vue atas objek data Set . :berpikir:

Untuk orang-orang seperti saya yang bertanya-tanya tentang peta jalan untuk ini, Evan You mengatakan dalam video ini bahwa dukungan Peta dan Set "kemungkinan" akan tiba pada 2,6, tetapi itu pada bulan Mei, jadi hanya itu yang saya tahu.

@yyx990803 Sangat disayangkan bahwa masalah di pelacak ini ditandai sebagai ditutup, terutama jika Anda mempertimbangkan untuk menambahkan dukungan dalam waktu dekat. Di mana kami dapat mengikuti perkembangan fitur ini? Apakah ada masalah lain di suatu tempat?

Hanya bertanya-tanya demi argumen, dan mungkin saya salah melakukannya, tetapi karena Anda dapat melacak mutasi array menggunakan Metode Mutasi, tidak bisakah Anda melacak array objek dan menyelesaikannya secara logis? Anda tidak mendapatkan semua fitur yang sama diimplementasikan di Peta tetapi yang Anda inginkan akan dengan mudah diatasi terutama jika Anda menggunakan sesuatu seperti _ atau lodash.

Sedih tapi sampai tim menambahkan ini, kita mungkin harus menggunakan struktur data alternatif

Hanya ingin berpadu bahwa kami akan menggunakan Peta untuk struktur data kami, lalu memutuskan untuk tidak melakukannya karena kurangnya dukungan pihak pertama.

apakah ini didukung sekarang di Vue3 (yaitu, reaktif Map dan Set )?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat