vuejs utilizar tutorial mutations mutaciones modulos las español ejemplo acciones vue.js vue-component mapbox-gl-js vuejs2 vuex

vue.js - utilizar - ¿Cómo configurar un estado centralizado para un mapa mapbox en Vuex?



vuex modulos (1)

Acabo de empezar a usar vuex con vue. Sí (más o menos) entiendo los documentos. Tengo un problema específico para el cual no estoy seguro de si debo usar vuex y, si es así, cómo hacerlo.

Tengo una aplicación en la que mapa (s) mapbox están omnipresentes en varios diseños y componentes, etc. Como haré varios componentes vue de archivo único pero estoy trabajando con una misma instancia de un mapa mapbox, creo que tiene sentido tener el mapbox mapa iniciado y administrado en la tienda vuex. Entonces, por ejemplo, cuando cambio el diseño del mapa o alguna otra cosa, se reflejará en todos los componentes.

Cuando continúo en esta dirección, me desconcierta un par de cosas:

  1. El mapa no es solo una variable / matriz, sino una instancia del mapa de la clase mapbox. Entonces, supongo que el estado inicial es un objeto vacío y luego debe inicializarse. ¿Correcto?
  2. La inicialización es asíncrona y solo puede ocurrir después de que se cargue la página, supongo. ¡¿Por qué mi código a continuación no funciona ?!

Intenté seguir:

Hizo un módulo mapboxmap, con

mapboxmap.js

import simple from ''../../components/simplestyle'' let mapboxgl = require(''mapbox-gl/dist/mapbox-gl.js'') // initial state const state = { myMap: {}, mapLoaded: false } const mutations = { loadMap (state, myMap) { state.myMap = myMap state.mapLoaded = true } } const actions = { loadMap (context) { ''use strict'' mapboxgl.accessToken = ''mysecretmapboxcode'' let myMap = new mapboxgl.Map({ container: ''map'', style: simple, hash: true, center: [-74.0073, 40.7124], zoom: 16 }) context.commit(''loadMap'', myMap) } } export default { state, mutations, actions }

Y como componente:

Maplayout.vue

<template> <div> <div id=''map'' class=''map''> </div> </div> </template> <script type=''text/babel''> export default { mounted () { this.computed.myMapForView.set().then(() => this.computed.myMapForView.get()) }, computed: { myMapForView: { // getter get: function () { return this.$store.state.myMap }, // setter set: function () { this.$store.dispatch(''loadMap'') } } } } </script>

Lo cual no funciona. Cualquier sugerencia sobre el enfoque de la solución y la forma específica de hacerlo es muy apreciada.

Aparece un mensaje de error en el navegador:

vue.runtime.common.js?d43f:433 TypeError: Cannot read property ''myMapForView'' of undefined at VueComponent.mounted (eval at 162 (0.ce2d9bf….js:21), <anonymous>:8:18) at callHook (eval at <anonymous> (app.js:794), <anonymous>:2335:19) at Object.insert (eval at <anonymous> (app.js:794), <anonymous>:2525:5) at invokeInsertHook (eval at <anonymous> (app.js:794), <anonymous>:4352:28) at VueComponent.patch [as __patch__] (eval at <anonymous> (app.js:794), <anonymous>:4508:5) at VueComponent.Vue._update (eval at <anonymous> (app.js:794), <anonymous>:2222:19) at VueComponent.eval (eval at <anonymous> (app.js:794), <anonymous>:2189:10) at Watcher.get (eval at <anonymous> (app.js:794), <anonymous>:1652:27) at Watcher.run (eval at <anonymous> (app.js:794), <anonymous>:1721:22) at flushSchedulerQueue (eval at <anonymous> (app.js:794), <anonymous>:1539:13) logError @ vue.runtime.common.js?d43f:433

EDITAR: Después de cambiar a this.myMapForView de this.computed.myMapForView recibí el siguiente mensaje de error en el navegador:

vue.runtime.common.js?d43f:433 TypeError: Cannot read property ''set'' of undefined at VueComponent.mounted (eval at 162 (0.85b2be9….js:21), <anonymous>:6:22) at callHook (eval at <anonymous> (app.js:794), <anonymous>:2335:19) at Object.insert (eval at <anonymous> (app.js:794), <anonymous>:2525:5) at invokeInsertHook (eval at <anonymous> (app.js:794), <anonymous>:4352:28) at VueComponent.patch [as __patch__] (eval at <anonymous> (app.js:794), <anonymous>:4508:5) at VueComponent.Vue._update (eval at <anonymous> (app.js:794), <anonymous>:2222:19) at VueComponent.eval (eval at <anonymous> (app.js:794), <anonymous>:2189:10) at Watcher.get (eval at <anonymous> (app.js:794), <anonymous>:1652:27) at Watcher.run (eval at <anonymous> (app.js:794), <anonymous>:1721:22) at flushSchedulerQueue (eval at <anonymous> (app.js:794), <anonymous>:1539:13) logError @ vue.runtime.common.js?d43f:433


Me parece que es new mapboxgl.Map() es una función asincrónica y en vuex Las acciones pueden contener operaciones asincrónicas arbitrarias, no mutaciones ni mutaciones . las funciones del controlador de mutación deben ser sincrónicas.

Entonces deberías hacer un new mapboxgl.Map() en acciones como las siguientes:

import simple from ''../../components/simplestyle'' let mapboxgl = require(''mapbox-gl/dist/mapbox-gl.js'') // initial state const state = { myMap: {}, mapLoaded: false } const mutations = { loadMap (state, myMap) { state.myMap = myMap } } const actions = { loadMap (context) { ''use strict'' mapboxgl.accessToken = ''mysecretmapboxkey'' var myMap = new mapboxgl.Map({ container: ''map'', style: simple, hash: true, center: [-74.0073, 40.7124], zoom: 16 }) context.commit(''loadMap'', myMap) } } export default { state, mutations, actions }

Editar :

Dado que las interacciones de su mouse están causando cambios en el estado, puede tener una propiedad calculada en su instancia vue con getter y setter , como por ejemplo:

computed: { myMapForView: { // getter get: function () { return this.$store.state. myMap }, // setter set: function (newMap) { this.$store.commit(''loadMap'', newMap) } } }

Working Fiddle: http://jsfiddle.net/aucqteLn/

También verifique: la tienda Vuex con "strict: true" no funciona