2017-06-27 7 views
6

In meiner Eltern vue Komponente habe ich ein user Objekt.VueJS richtigen Weg Prop bearbeiten, ohne Eltern Daten zu ändern

Wenn ich das Benutzerobjekt zu einer untergeordneten Komponente als Stütze passieren:

<child :user="user"></child> 

und in meinem Kind Komponente I aktualisieren user.name, wird es auch in der Mutter aktualisiert.

Ich möchte das Benutzerobjekt in der untergeordneten Komponente bearbeiten, ohne dass die Änderungen in dem Benutzerobjekt widergespiegelt werden, das sich in der übergeordneten Komponente befindet.

Gibt es einen besseren Weg dies zu erreichen als das Klonen des Objekts mit: ?

Antwort

11

Sie müssen das Objekt JSON nicht verwenden.

const child = { 
    props:["user"], 
    data(){ 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    } 
} 

Verwenden localUser (oder was auch immer Sie es nennen wollen) in Ihrem Kind.

bearbeiten

ich eine Geige für eine andere Antwort auf diese Frage erstellt geändert hatte das obige Konzept und @ user3743266

fragte

Ich komme mit diesem selbst, und ich in den Griff zu demonstrieren Finde das sehr nützlich. Ihr Beispiel funktioniert gut. Im Kind haben Sie ein Element in Daten erstellt, das eine Kopie der Requisite enthält, und das Kind arbeitet mit der Kopie . Interessant und nützlich, aber ... es ist mir nicht klar , wenn die lokale Kopie aktualisiert wird, wenn etwas anderes die Eltern ändert. Ich habe deine Geige modifiziert und die v-ifs entfernt, so dass alles sichtbar ist, und Duplizierung der Edit-Komponente. Wenn Sie den Namen in einer Komponente ändern, ist der andere verwaist und erhält keine Änderungen?

Die aktuelle Komponente wie folgt aussieht:

Vue.component('edit-user', { 
    template: ` 
    <div> 
    <input type="text" v-model="localUser.name"> 
    <button @click="$emit('save', localUser)">Save</button> 
    <button @click="$emit('cancel')">Cancel</button> 
    </div> 
    `, 
    props: ['user'], 
    data() { 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    } 
}) 

Weil ich die Design-Entscheidung ein lokales kopieren des Benutzers verwenden gemacht, @ user3743266 korrekt ist, wird die Komponente nicht automatisch aktualisiert. Die Eigenschaftuser wird aktualisiert, aber localUser ist nicht. In diesem Fall wenn Sie lokale Daten automatisch aktualisieren wollten, wenn sich die Eigenschaft änderte, würden Sie einen Beobachter benötigen.

Vue.component('edit-user', { 
    template: ` 
    <div> 
    <input type="text" v-model="localUser.name"> 
    <button @click="$emit('save', localUser)">Save</button> 
    <button @click="$emit('cancel')">Cancel</button> 
    </div> 
    `, 
    props: ['user'], 
    data() { 
    return { 
     localUser: Object.assign({}, this.user) 
    } 
    }, 
    watch:{ 
    user(newUser){ 
     this.localUser = Object.assign({}, newUser) 
    } 
    } 
}) 

Hier ist die aktualisierte fiddle.

Damit haben Sie vollständige Kontrolle darüber, ob/wenn die lokalen Daten aktualisiert oder ausgegeben werden. Beispielsweise möchten Sie möglicherweise eine Bedingung überprüfen, bevor Sie den lokalen Status aktualisieren.

watch:{ 
    user(newUser){ 
     if (condition) 
     this.localUser = Object.assign({}, newUser) 
    } 
    } 

Wie ich an anderer Stelle gesagt, gibt es Zeiten, in denen Sie die Vorteile von Objekten nehmen möchten Eigenschaften wandelbar zu sein, aber es gibt auch Zeiten wie diesen, wo Sie mehr Kontrolle wünschen könnten.

+0

@ user3743266 Eine Erklärung hinzugefügt. – Bert

+1

Sehr schön. Das war sehr interessant, danke. Vue rockt meine Oma. Ich denke Evan You ist in Wirklichkeit ein Team von 30 Raketenwissenschaftlern. – bbsimonbb

+1

Sind Sie sicher? Ich würde sagen, dass dieser Thread und Ihre Antwort Tonnen von Wert haben. Fragen wie diese sind potenziell für alle relevant, die vue verwenden. Lass es, und es könnte ein langes und überraschendes Leben haben. – bbsimonbb

0

According to this, Kinder "kann nicht" und "sollte nicht" die Daten ihrer Eltern ändern. Aber here Sie können sehen, dass, wenn ein Elternteil einige reaktive Daten als eine Eigenschaft an ein Kind übergibt, ist es Pass-by-Referenz und das Elternteil sieht die Änderungen des Kindes. Das ist wahrscheinlich das, was du die meiste Zeit willst, oder? Sie ändern nur die Daten, die das Elternteil explizit freigegeben hat. Wenn Sie möchten, dass das Kind eine unabhängige Kopie von user hat, könnten Sie das vielleicht mit JSON.parse (JSON.stringify()) tun, aber passen Sie auf, dass Sie Vue-injected Eigenschaften serialisieren werden. Wann würdest du es tun? Denken Sie daran, dass Requisiten reaktiv sind, sodass die Eltern jederzeit einen neuen Benutzer senden und lokale Änderungen löschen können?

Vielleicht müssen Sie uns mehr darüber erzählen, warum Sie wollen, dass das Kind eine eigene Kopie hat? Was macht das Kind mit seiner Kopie? Wenn der Benutzer des Kindes auf systematische Weise vom übergeordneten Benutzer abgeleitet wird (indem Sie den gesamten Text oder etwas anderes überladen), sehen Sie sich die berechneten Eigenschaften an.

+1

Es ist nicht das, was Sie die meiste Zeit wollen, nein. Wenn sich der Eigenschaftswert ändert, werden die lokalen Daten * nicht * gelöscht (es sei denn, Sie haben dies ausdrücklich festgelegt). Es gibt eine Reihe von Gründen, warum Sie keine Änderungen an dem untergeordneten Objekt * sofort * im übergeordneten Objekt vornehmen möchten . Betrachten Sie den Fall von jemandem, der ihre Änderungen absagen möchte. Wenn Sie Änderungen an den Daten vornehmen, die in der Eigenschaft übergeben werden, müssen Sie eine zusätzliche Lösung finden, um all diese Änderungen rückgängig zu machen. Wenn Sie zuerst eine Kopie erstellen und nur Änderungen an dem übergeordneten Element vornehmen, wenn Sie die Daten ausgeben, können Sie jederzeit abbrechen. – Bert

+0

Sie sagen, dass Daten nicht gelöscht werden, aber genau das passiert in meinem [jsfiddle] (https://jsfiddle.net/bbsimonbb/32xoy9Lw/7/), wenn Sie reaktive Daten als Eigenschaft an ein Kind weitergeben. Eltern und Kind teilen eine Quelle der Wahrheit? Wie würden Sie Ihr Undo-Szenario implementieren? – bbsimonbb

+0

Ich sagte * Daten *, wie in Dateneigenschaften, nicht die Eigenschaft selbst. Ich habe deine [Geige] aktualisiert (https://jsfiddle.net/32xoy9Lw/10/). Beachten Sie, dass Sie jetzt Änderungen an dem Kind einfach rückgängig machen können, da das Kind nur dann Änderungen ausgibt, wenn Sie es beabsichtigen. Wenn Sie die Benutzereigenschaft direkt bearbeitet haben und Sie abbrechen möchten, müssen Sie den ursprünglichen Zustand speichern und wiederherstellen. Ich stimme dir zu, dass es * praktisch * ist, dass du Objekt- und Array-Eigenschaften mutieren kannst, aber auch weniger * wartbar *. Sie sollten vorsichtig sein, wenn Sie eine Eigenschaft mutieren. Es sollte nicht dein Standard sein. – Bert

0

können Sie eine Datenvariable mit den Informationen, die Sie lokal sein wollen editierbar und laden Sie den Wert in der erstellten Methode haben nur

data() { 
return { localUserData: {name: '', (...)} 
} 
(...) 
created() { 
    this.localUserData.name = this.user.name; 
} 

diese Weise können Sie es von Ihnen, welche Daten freihalten bearbeiten. Je nach Bedarf möchten Sie möglicherweise einen Watcher, um die lokalen Daten zu aktualisieren, falls sich die Benutzerreferenz ändert.

Verwandte Themen