VueJS tidak boleh mengemas kini komponen
P粉517475670
P粉517475670 2024-03-26 20:00:55
0
1
386

Saya mempunyai komponen Vue 1 ini yang mendapat objek sebagai prop yang mesti diisi oleh pengguna.

Objek mempunyai struktur berikut:

{
    property1: ...,
    property2: ...,
    inputs: {
        2130: { value: ..., comment: ... },
        2131: { ... },
        ...,
    }

}

Komponen ialah modal mudah dengan borang yang mengandungi semua input yang diperlukan. Saya ingin menyemak beberapa kandungan, melakukan pengiraan dan menukar gaya sel berdasarkan input pengguna.

Apabila modal dimuatkan, saya membina halaman, menetapkan model untuk input ini menggunakan idnya:

v-model="object.inputs[subgroup[1].dx.mob.id].comment"

(Nota: subgroup[1]是包含表结构“定义”的另一个对象的一部分,通过执行 inputs[subgroup[1].dx.mob.id] Saya menjangkakan medan jadual yang dipautkan dengan input objek yang sepadan)

Masalahnya, tidak kira apa yang saya cuba, halaman itu tidak dipaparkan semula. <input> Medan itu tidak menyimpan nilai, ia hilang sebaik sahaja saya mengkliknya.

Apa yang lebih pelik ialah nilai sebenarnya telah ditetapkan, tetapi satu-satunya cara untuk membuat komponen itu dipaparkan semula dan melakukan semua pemeriksaan dan penggayaan yang baik yang saya perlukan dia lakukan ialah dengan menutup dan membuka semula modal atau dengan menetapkannya atas meja ibu bapa v-if.

Ini jelas bukan pilihan yang boleh dilaksanakan

  • Saya memerlukan halaman untuk responsif
  • Mencipta semula komponen (pada setiap perubahan input) mengambil terlalu banyak masa

Ini yang saya cuba:

  • Bina pemerhati secara dinamik untuk setiap input
    • Tetapi vm.$watch objek itu tidak dapat ditemui atas sebab tertentu.
...forEach((input, index)=>{
    vm.$watch(`object.inputs[${index}].comment`, function(){
            this.$forceUpdate();
        })
}
  • Kembalikan input dalam harta yang dikira dan amati

    • Tetapi halaman tidak dapat mengesan perubahan
  • Mulakan secara manual pada acara @change dan @input this.$forceUpdate()

    • Tetapi $forceUpdate bukan fungsi
  • Isytiharkan pembilang dalam data dan naikkannya pada acara @perubahan dan @input.

    • Tetapi halaman masih tidak dikemas kini.
  • Letakkan v-if pada objek yang tidak kelihatan

    • Tetapi hanya objek tersebut yang dipaparkan semula
  • Gunakan atribut data untuk menukar atribut :key bagi komponen

    • Tetapi tiada apa yang berlaku

Seperti yang dijangkakan, satu-satunya cara yang boleh saya lakukan adalah dengan memusnahkan dan mencipta semula komponen tersebut.

Ada sesiapa ada penyelesaian?

Penyelesaian Hodoh: Selepas beberapa percubaan yang gagal, saya menemui sesuatu yang berkesan, walaupun dengan cara yang salah. mana-mana yang sebenar Jawapan masih sangat dialu-alukan.

Pada asasnya, saya berjaya memaksa komponen untuk memaparkan semula:

  • Isytiharkan pembolehubah baharu dalam data, saya menamakannya key (dalam kes saya ia adalah nombor, tetapi apa-apa pun boleh)
  • Buat fungsi kemas kini yang menukar update 函数,将 key daripada 1 kepada 0 dan sebaliknya.
  • Ikat fungsi ini pada setiap input atau pilihan @blur acara
  • Memandangkan keseluruhan modal saya dipaparkan berdasarkan sifat yang dikira, saya melakukan beberapa bacaan pada key di dalam fungsi itu (dalam Kes saya ialah saya memberikan nilainya kepada pembolehubah baharu dan kemudian logkannya (bukan Menentukan yang mana satu daripada dua pencetus rendering, tetapi saya rasa yang pertama adalah Cukup))
... 
data: function() {
      return {
        ... ,
        key: 0
      };   
},

...

methods: {
    ... ,
    update: function(){
        this.key = this.key == 0 ? 1 : 0
    }
},
computed: {
    ... ,
    testData: function () { //this functions builds an object that is used to render the page  
        var data = []
        var __self = this
        var blu = this.key // This is the line where i read key
        console.log(blu)
        this.test.inputs.forEach(function(input){

            var slug = input.slug.replaceAll('#', '').split('-')
        
            __self.setItem(data, slug, input)

        })
     
        console.log('data', data)
        return data // this value gets then passed to Object.entries() to get an iterable object I build the page with
    } 
}

P粉517475670
P粉517475670

membalas semua(1)
P粉198749929

Jawapan yang lebih baik

Selepas penyahpepijatan lembut, saya berjaya menyelesaikan masalah ini.

Pada asasnya, komponen yang saya huraikan dalam soalan digunakan untuk dua halaman berbeza: halaman "Buat" dan halaman "Edit". Jantung saya berdegup kencang apabila saya melihat semuanya berfungsi seperti yang diharapkan dalam halaman suntingan.

Apa yang berlaku:

Satu-satunya perbezaan antara cara komponen digunakan dalam dua halaman ialah data yang dihantar kepadanya. Dalam halaman Edit, setiap objek diisi kerana data sudah ada, manakala dalam halaman Cipta, setiap objek jelas kosong.

Memandangkan saya memerlukan objek yang boleh digunakan, saya perlu mengisinya dengan input kosong supaya saya boleh mengaksesnya kemudian.

Saya dengan bodohnya mencuba menetapkan harta secara manual seperti ini:

objects[index].inputs = {}

Dapatkan bahawa memberikan sifat kepada objek reaktif secara automatik akan menjadikan sifat itu reaktif juga. Oh budak, adakah saya salah.

Pengambil dan penetap responsif Vue:

Untuk menjadikan sesuatu responsif, vue mengatasi pemula dan penetap kelas Objek lalai. Tetapi ini hanya berlaku dalam keadaan tertentu:

  • Atribut ini mesti ditambah melalui Vue.set()this.$set()
  • Semua hartanah induk mesti responsif juga

Sebagai contoh, selepas beberapa percubaan, tetapkan objects[index].inputs = {} 后,我尝试使用 this.$set() untuk mengisi input saya.

Ini tidak berfungsi kerana saya tidak membuat .inputs reaktif sama ada.

Jadi saya terpaksa

this.$set('objects[${index}].inputs', {})

sebelum

this.$set(`objects[${index}].inputs[${input.id}].value`, null)
this.$set(`objects[${index}].inputs[${input.id}].comment`, null)

Kesimpulan:

Jika anda mempunyai masalah kereaktifan, nasihat saya ialah log objek tersebut dan periksa sama ada objek tersebut serta objek induknya mempunyai pengambil dan penetap yang betul.

Ingat, jika anda ingin menambah sifat baharu pada objek reaktif, anda mesti $set()nya.

Objek tindak balas:
Objek bukan reaktif:
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan