2017-04-21 8 views
2

Ich habe eine Vue-Komponente, die an mehreren Stellen in ein großes Legacy-System (nicht Vue) eingebettet werden muss. Die Komponente führt einige AJAX-Anforderungen aus und zeigt Informationen basierend auf einem Array von Datenbankdatensatz-IDs an, die normalerweise zum Zeitpunkt des Ladens der Seite empfangen werden. Das Array wird vom Server direkt in die Seitenvorlage eingebettet und als Requisiten an die Komponente übergeben, etwa so:Binding Vue Komponentendaten in externen Zustand

let config = { 
    records: {{ template_code_outputting_array }}, 
    ...otherConfigOptions 
} 

let app = new Vue({ 
    el: '#app', 
    store, 
    render: h => h(ComponentName, { 
    props: config 
    }) 
}) 

Mein Problem ist, dass auf einem der Bildschirme muss es in die Datenbank Datensätze eingebettet werden kann vom Benutzer dynamisch mit einer AJAX-Schnittstelle vom Typ Search-and-Add ausgewählt werden (anstatt beim Laden der Seite voreingestellt zu sein). Daher muss die Komponente mit der Auswahl des Benutzers synchronisiert werden, damit sie erneut gerendert werden kann notwendig.

Ich habe eine funktionierende Lösung, aber es ist alles andere als ideal; Ich rufe zur Zeit direkt eine Methode auf der Komponente jedes Mal, wenn der Benutzer eine Änderung ihre Auswahl macht, die neue Auswahl vorbei, so dass die Komponente eine eigene interne Kopie aktualisieren:

app.$children[0].recordsChanged(newSelection) 

Aber offensichtlich ist dies nicht reaktiv, und es fühlt sich irgendwie hacky an. Ich habe das Gefühl, ich sollte nicht direkt eine Komponente ansprechen, und die Funktion, die ich anrufe, ist nur für den externen Gebrauch da; nichts in der Komponente verwendet es.

Ich habe Bindungswerte versucht in Daten auf globale Variablen (die wiederum ist nicht ideal, aber ich habe nicht viel Auswahl), dann das Hinzufügen einer Uhr Verfahren eine erneute Rendern auf Veränderung auszulösen. Offensichtlich funktionieren skalare Werte nicht, da sie nach Wert und nicht nach Referenz sind, aber das Einschließen in ein Objekt scheint auch nicht zu funktionieren. Sie binden gut und nehmen die angegebenen Anfangswerte an, aber das Aktualisieren des Objekts (entweder das direkte Ändern seiner Werte oder das Ersetzen des Objekts durch ein neues) scheint die Methode watch oder irgendeine Reaktivität nicht auszulösen.

Gibt es Best Practices dafür oder ist mein derzeitiger Ansatz das Beste, auf das ich hoffen kann?

+1

Warum gewohnt verwenden Sie einen vue Eventbus? wie 'var bus = new Vue ({})'. dann können Sie tun, wo Sie wollen 'bus. $ emittieren (" someEvent ", {new: data})' und in Ihrer Komponente tun 'bus. $ on (" someEvent ", doSomething)'. Stellen Sie sicher, die Busvariable dem Fenster – AfikDeri

+0

@AfikDeri zuzuweisen Das hat tatsächlich viel geholfen, also danke. Ich war in der Lage, eine Funktion zu exportieren, die die Emission umhüllt, so dass niemand, der Änderungen am externen Code vornimmt, Vue-Kenntnisse benötigt. Es wäre immer noch schön, wenn ich es total reaktiv machen und den Funktionsaufruf ganz vermeiden könnte, aber ich fange an zu denken, dass es keinen saubereren Weg gibt, es zu tun. –

Antwort

1

Ein Event-Bus (wie von AfikDeri in den Kommentaren vorgeschlagen) ist eine gute Lösung. Es bietet eine direkte Schnittstelle.

Die Reaktivierung Ihrer Daten ist ebenfalls möglich, with some caveats. Ein Objekt, das zum Initialisieren eines Datenelements verwendet wird, wird selbst reaktiv gemacht. Wenn die Dinge, die Ihr Array ändern do so in the approved ways, sollten Sie die Änderungen in Ihrem Vue sehen.

let stuff = [2, 3, 5]; 
 

 
const v = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    reactiveStuff: stuff 
 
    }, 
 
    components: { 
 
    myComponent: { 
 
     props: ['arr'], 
 
     template: '<div><div v-for="item in arr">{{item}}</div></div>' 
 
    } 
 
    } 
 
}); 
 

 
setTimeout(() => { 
 
    stuff.push(7); 
 
}, 1200);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script> 
 
<my-component id="app" :arr="reactiveStuff"> 
 
</my-component>

Verwandte Themen