Apakah ada cara yang tepat untuk menyetel ulang data awal komponen di vuejs?

93

Saya memiliki komponen dengan kumpulan data awal tertentu:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', // possible values: 'getUserInput', 'confirmGeocodedValue'
        submitButtonText: 'Lookup', // possible values 'Lookup', 'Yes'
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        }
}

Ini adalah data untuk jendela modal, jadi ketika itu menunjukkan saya ingin memulai dengan data ini. Jika pengguna membatalkan dari jendela saya ingin mengatur ulang semua data ke ini.

Saya tahu saya dapat membuat metode untuk mengatur ulang data dan secara manual mengatur semua properti data kembali ke aslinya:

reset: function (){
    this.modalBodyDisplay = 'getUserInput';
    this.submitButtonText = 'Lookup';
    this.addressToConfirm = null;
    this.bestViewedByTheseBounds = null;
    this.location = {
        name: null,
        address: null,
        position: null
    };
}

Tapi ini sepertinya sangat ceroboh. Ini berarti bahwa jika saya membuat perubahan pada properti data komponen, saya harus memastikan bahwa saya ingat untuk memperbarui struktur metode reset. Itu tidak terlalu buruk karena ini adalah komponen modular kecil, tetapi itu membuat bagian pengoptimalan otak saya menjerit.

Solusi yang saya pikir akan berhasil adalah dengan mengambil properti data awal dalam sebuah readymetode dan kemudian menggunakan data yang disimpan itu untuk mengatur ulang komponen:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', 
        submitButtonText: 'Lookup', 
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        },
        // new property for holding the initial component configuration
        initialDataConfiguration: null
    }
},
ready: function (){
    // grabbing this here so that we can reset the data when we close the window.
    this.initialDataConfiguration = this.$data;
},
methods:{
    resetWindow: function (){
        // set the data for the component back to the original configuration
        this.$data = this.initialDataConfiguration;
    }
}

Tetapi initialDataConfigurationobjek berubah seiring dengan data (yang masuk akal karena dalam metode baca kita initialDataConfigurationmendapatkan ruang lingkup fungsi data.

Apakah ada cara untuk mengambil data konfigurasi awal tanpa mewarisi cakupan?

Apakah saya terlalu memikirkan hal ini dan ada cara yang lebih baik / lebih mudah untuk melakukan ini?

Apakah hardcode data awal satu-satunya pilihan?

Chris Schmitz
sumber
Apakah Anda menggunakan v-show atau v-if untuk menampilkan modal?
Rwd
Saya menggunakan bootstrap untuk css jadi saya menggunakan modal bawaan yang memanfaatkan jquery untuk menampilkan dan menyembunyikan. Jadi pada dasarnya bagian jendela komponen selalu ada, hanya tersembunyi.
Chris Schmitz

Jawaban:

125
  1. mengekstrak data awal menjadi fungsi di luar komponen
  2. gunakan fungsi itu untuk mengatur data awal dalam komponen
  3. gunakan kembali fungsi itu untuk mengatur ulang keadaan saat diperlukan.

// outside of the component:
function initialState (){
  return {
    modalBodyDisplay: 'getUserInput', 
    submitButtonText: 'Lookup', 
    addressToConfirm: null,
    bestViewedByTheseBounds: null,
    location:{
      name: null,
      address: null,
      position: null
    }
  }
}

//inside of the component:
data: function (){
    return initialState();
} 


methods:{
    resetWindow: function (){
        Object.assign(this.$data, initialState());
    }
}

Linus Borg
sumber
5
Itu berhasil. Terima kasih! Saya melakukan sedikit pengeditan pada jawabannya, tetapi hanya karena komponen vue memerlukan fungsi yang dikembalikan untuk data, bukan hanya objek. Konsep jawaban Anda pasti berfungsi dan benar, edit hanya untuk menjelaskan bagaimana vuejs menangani komponen.
Chris Schmitz
3
Anda benar tentang fungsi untuk properti data, bahwa saya ceroboh. Terima kasih atas pengeditannya.
Linus Borg
13
Sekarang memberikan kesalahan:[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
Sankalp Singha
34
@SankalpSingha Vue 2.0 tidak mengizinkan Anda melakukan itu lagi. Anda bisa menggunakan Object.assignsebagai gantinya. Berikut adalah kode yang berfungsi: codepen.io/CodinCat/pen/ameraP?editors=1010
CodinCat
3
Untuk masalah ini - [Vue warn]: Hindari mengganti $ data root instance. Gunakan properti data bersarang sebagai gantinya, coba ini. $ Data.propName = "nilai baru";
Stanislav Ostapenko
33

Untuk mengatur ulang komponen datadalam contoh komponen saat ini, Anda dapat mencoba ini:

Object.assign(this.$data, this.$options.data())

Secara pribadi saya memiliki komponen modal abstrak yang menggunakan slot untuk mengisi berbagai bagian dialog. Ketika modal yang dikustomisasi membungkus modal abstrak itu, data yang dirujuk dalam slot termasuk dalam lingkup komponen induk . Berikut adalah opsi dari modal abstrak yang menyetel ulang data setiap kali modal yang disesuaikan ditampilkan (kode ES2015):

watch: {
    show (value) { // this is prop's watch
      if(value) {
        Object.assign(this.$parent.$data, this.$parent.$options.data())
      }
    }
}

Anda tentu saja dapat menyesuaikan implementasi modal Anda - di atas mungkin juga dijalankan dalam beberapa hal cancel.

Ingatlah bahwa mutasi $parentopsi dari anak tidak disarankan, namun saya pikir ini dapat dibenarkan jika komponen induk hanya menyesuaikan modal abstrak dan tidak lebih.

gertas
sumber
1
Teknik ini sekarang memberikan peringatan VueJS; lihat stackoverflow.com/questions/40340561/…
Kivi Shapiro
7
Perhatian, ini tidak mengikat konteks ke dalam data. Jadi jika Anda menggunakan thiske dalam datametode Anda dapat menerapkan konteks dengan:Object.assign(this.$data, this.$options.data.apply(this))
Ifnot
Apa keuntungan dari cara ini dibandingkan dengan location.reload ()?
Carlos
30

Perhatian, Object.assign(this.$data, this.$options.data())tidak mengikat konteks ke dalam data ().

Jadi gunakan ini:

Object.assign(this.$data, this.$options.data.apply(this))

cc jawaban ini awalnya di sini

roli roli
sumber
3

Jika Anda terganggu oleh peringatan tersebut, ini adalah metode yang berbeda:

const initialData = () => ({})

export default {
  data() {
    return initialData();
  },
  methods: {
    resetData(){
      const data = initialData()
      Object.keys(data).forEach(k => this[k] = data[k])
    }
  }
}

Tidak perlu repot dengan $ data.

srmico
sumber
2

Saya harus mengatur ulang data ke keadaan semula di dalam komponen anak, inilah yang berhasil untuk saya:

Komponen induk, memanggil metode komponen anak:

     <button @click="$refs.childComponent.clearAllData()">Clear All</button >

     <child-component ref='childComponent></child-component>

Komponen anak:

  1. mendefinisikan data dalam fungsi luar,
  2. menugaskan objek data ke dan di luar fungsi
  3. mendefinisikan metode clearallData () yang akan dipanggil oleh komponen induk

    function initialState() {
       return { 
         someDataParameters : '',
         someMoreDataParameters: ''
              }
      }
    
    export default {
       data() {
        return initialState();
      },
        methods: {
      clearAllData() {
      Object.assign(this.$data, initialState());
    },
    
Armin
sumber