2016-12-29 5 views
1

Wenn ich strict: true stelle ich Fehler:Vuex Geschäft mit „streng: true“ funktioniert nicht

vue.js:525 [Vue warn]: Error in watcher "state" 
(found in root instance) 
warn @ vue.js:525 
run @ vue.js:1752 
update @ vue.js:1720 
notify @ vue.js:584 
reactiveSetter @ vue.js:814 
Transform.resize @ transform.js:169 
e.resize @ map.js:343 
e._onWindowResize @ map.js:1204 

vue.js:1756 Uncaught Error: [vuex] Do not mutate vuex store state outside mutation handlers. 
    at assert (vuex.js:182) 
    at Vue$3.store._vm.$watch.deep (vuex.js:714) 
    at Watcher.run (vue.js:1746) 
    at Watcher.update (vue.js:1720) 
    at Dep.notify (vue.js:584) 
    at Transform.reactiveSetter [as width] (vue.js:814) 
    at Transform.resize (transform.js:169) 
    at e.resize (map.js:343) 
    at e._onWindowResize (map.js:1204) 

Als ich eingestellt strict: false oder die Zeile auslassen vollständig, es funktioniert gut. Es wird empfohlen, im strikten Modus zu arbeiten: Was kann ich tun, um den Fehler zu vermeiden? Ich glaube nicht, dass ich den Speicher außerhalb von Mutationshandlern in meinem Code mutiere !?

Siehe Verhalten in this fiddle.

+0

Sie sollten nicht versuchen, die gesamte Map im vuex-Store zu speichern, da sie in jeder interaktiven Mapbox geändert wird – Nora

+0

@Nora Dann wie kann man die Map-Variable über mehrere Komponenten hinweg verwenden und davon profitieren, was vuex bietet? – Saurabh

+0

Imo wäre am besten, allgemeine Funktionalität in ein separates Modul/Service zu extrahieren und in die Komponenten wo nötig zu importieren. Meiner Ansicht nach sollte Vuex-Speicher zum Verwalten des Anwendungsstatus und nicht zum Speichern globaler Variablen/Objekte verwendet werden. – Nora

Antwort

2

Obwohl Sie den Geschäftszustand nicht außerhalb von Mutationshandlern mutieren, wird die mapboxgl.Map-Instanz ausgeführt.

var myMap = new mapboxgl.Map({ 
    container: 'map', 
    style: 'mapbox://styles/mapbox/streets-v9', 
    hash: true, 
    center: [-74.0073, 40.7124], 
    zoom: 16 
}) 

Hier finden Sie eine Instanz einer Map-Klasse erstellen, die (einschließlich einer Bezugnahme auf das DOM-Element) und Methoden einen eigenen Staat hat. Diese Karteninstanz überwacht DOM-Ereignisse (Benutzerinteraktion) und aktualisiert ihren eigenen Status, wodurch die Regel von Vuex verletzt wird.

Mein Vorschlag ist, dass Sie eine Vue-Komponente für die Karte erstellen sollten, wie andere sagten. Da die Map-Instanz einen Verweis auf das DOM-Element <div id="map"> hat, gehört sie für mich zur View-Ebene, nicht zur Store-Ebene. Vue ist ein View-Layer-Framework und konzentriert sich auf alles, was mit DOM zu tun hat, während Vuex eine State-Management-Bibliothek ist, die am besten für serialisierbare Anwendungszustände (wie JSON-Daten) geeignet ist und von tatsächlichen DOM-Elementen abgekoppelt werden sollte.

Bei der Kommunikation mit anderen Komponenten können Sie, wenn es sich um eine direkte Eltern-Kind-Beziehung handelt, Requisiten/Kinderreferenzen und Ereignisrückrufe verwenden; Andernfalls können Sie einen bestimmten Status (z. B. Zoom) aus der Karteninstanz extrahieren/kopieren und in vuex store speichern oder global event bus verwenden.

Als Randnotiz gibt es keine Garantie, dass Vue mit jedem Libraray, das das DOM mutiert, gut spielt. Der Benutzer, der eine solche Bibliothek verwendet, ist für die Verwaltung verantwortlich, und die Lebenszyklus-Hooks sind der beste Ort, um solche Dinge zu tun.

Verwandte Themen