Gibt es eine geeignete Möglichkeit, die Anfangsdaten einer Komponente in vuejs zurückzusetzen?

89

Ich habe eine Komponente mit einem bestimmten Satz von Startdaten:

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

Dies sind Daten für ein modales Fenster. Wenn es angezeigt wird, möchte ich, dass es mit diesen Daten beginnt. Wenn der Benutzer das Fenster abbricht, möchte ich alle Daten auf dieses zurücksetzen.

Ich weiß, dass ich eine Methode zum Zurücksetzen der Daten erstellen und einfach alle Dateneigenschaften manuell auf das Original zurücksetzen kann:

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

Aber das scheint wirklich schlampig. Wenn ich jemals Änderungen an den Dateneigenschaften der Komponente vornehme, muss ich sicherstellen, dass ich daran denke, die Struktur der Rücksetzmethode zu aktualisieren. Das ist nicht absolut schrecklich, da es sich um eine kleine modulare Komponente handelt, aber es lässt den Optimierungsteil meines Gehirns schreien.

Die Lösung, von der ich dachte, dass sie funktionieren würde, wäre, die anfänglichen Dateneigenschaften in einer readyMethode zu erfassen und diese gespeicherten Daten dann zum Zurücksetzen der Komponenten zu verwenden:

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

Das initialDataConfigurationObjekt ändert sich jedoch zusammen mit den Daten (was sinnvoll ist, da bei der initialDataConfigurationLesemethode der Umfang der Datenfunktion ermittelt wird.

Gibt es eine Möglichkeit, die anfänglichen Konfigurationsdaten abzurufen, ohne den Bereich zu erben?

Überdenke ich das und es gibt einen besseren / einfacheren Weg, dies zu tun?

Ist die Hardcodierung der Anfangsdaten die einzige Option?

Chris Schmitz
quelle
Verwenden Sie v-show oder v-if, um das Modal anzuzeigen?
Rwd
Ich verwende Bootstrap für das CSS, also verwende ich es in Modal, das JQuery zum Ein- und Ausblenden nutzt. Im Wesentlichen ist der Fensterteil der Komponente immer vorhanden, nur versteckt.
Chris Schmitz

Antworten:

117
  1. Extrahieren Sie die Anfangsdaten in eine Funktion außerhalb der Komponente
  2. Verwenden Sie diese Funktion, um die Anfangsdaten in der Komponente festzulegen
  3. Verwenden Sie diese Funktion erneut, um den Status bei Bedarf zurückzusetzen.

// 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
quelle
5
Das hat es geschafft. Vielen Dank! Ich habe die Antwort geringfügig bearbeitet, aber nur, weil für eine vue-Komponente eine Funktion erforderlich ist, die für Daten anstelle nur eines Objekts zurückgegeben wird. Ihr Antwortkonzept funktioniert definitiv und ist korrekt. Die Bearbeitung dient nur dazu, zu berücksichtigen, wie vuejs mit Komponenten umgeht.
Chris Schmitz
3
Sie haben Recht mit der Funktion für die Dateneigenschaft, das war ich schlampig. Danke für die Bearbeitung.
Linus Borg
13
Es gibt jetzt einen Fehler:[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
Sankalp Singha
33
@SankalpSingha Vue 2.0 erlaubt Ihnen das nicht mehr. Sie können Object.assignstattdessen verwenden. Hier ist der Arbeitscode
CodinCat
3
Für dieses Problem - [Vue warn]: Vermeiden Sie das Ersetzen von Instanzstammdaten. Verwenden Sie stattdessen verschachtelte Dateneigenschaften. $ Data.propName = "neuer Wert";
Stanislav Ostapenko
31

So setzen Sie die Komponente datain einer aktuellen Komponenteninstanz zurück:

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

Privat habe ich eine abstrakte modale Komponente, die Slots verwendet, um verschiedene Teile des Dialogs zu füllen. Wenn angepasste Modal-Wraps dieses abstrakte Modal umschließen, gehören die in Slots angegebenen Daten zum übergeordneten Komponentenbereich . Hier ist die Option des abstrakten Modals, das die Daten jedes Mal zurücksetzt, wenn das angepasste Modal angezeigt wird (ES2015-Code):

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

Sie können Ihre modale Implementierung natürlich fein abstimmen - obiges kann auch in einem cancelHook ausgeführt werden.

Bedenken Sie, dass die Mutation von $parentOptionen aus dem Kind nicht empfohlen wird. Ich denke jedoch, dass dies gerechtfertigt sein kann, wenn die übergeordnete Komponente nur das abstrakte Modal anpasst und nicht mehr.

gertas
quelle
1
Diese Technik gibt jetzt eine VueJS-Warnung aus. siehe stackoverflow.com/questions/40340561/…
Kivi Shapiro
7
Achtung, dies bindet den Kontext nicht ein data. Wenn Sie also thisIhre dataMethode verwenden, können Sie den Kontext anwenden mit:Object.assign(this.$data, this.$options.data.apply(this))
Ifnot
Was ist der Vorteil dieser Methode gegenüber location.reload ()?
Carlos Pozos
27

Achtung, Object.assign(this.$data, this.$options.data())bindet den Kontext nicht an data ().

Verwenden Sie also Folgendes:

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

cc diese Antwort war ursprünglich hier

roli roli
quelle
1

Ich musste die Daten innerhalb einer untergeordneten Komponente auf den ursprünglichen Zustand zurücksetzen. Dies hat bei mir funktioniert:

Übergeordnete Komponente, die die Methode der untergeordneten Komponente aufruft:

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

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

Untergeordnete Komponente:

  1. Definieren von Daten in einer externen Funktion,
  2. Zuweisen des Datenobjekts zu und außerhalb der Funktion
  3. Definieren der clearallData () -Methode, die von der übergeordneten Komponente aufgerufen werden soll

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

Wenn Sie sich über die Warnungen ärgern, ist dies eine andere Methode:

const initialData = () => ({})

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

Sie müssen sich nicht mit $ data anlegen.

srmico
quelle