如何在Vuex中为地图集地图设置集中状态?

mus*_*ons 6 vue.js mapbox-gl-js vue-component vuex vuejs2

我刚开始使用vuex和vue.我(大致)理解文档.我有一个特定的问题,我不确定是否应该使用vuex,如果是的话,如何去做.

我有一个应用程序,其中mapbox地图在各种布局和组件等无处不在.因为我将制作几个vue单个文件组件,但正在使用一个相同的mapbox地图实例,我认为有了mapbox是有道理的在vuex商店中启动和管理的地图.因此,例如,当我更改地图布局或其他内容时,它将反映在所有组件中.

当我继续朝着这个方向前进时,我对以下几点感到困惑:

  1. 地图不仅仅是变量/数组,而是mapbox类映射的实例.所以我认为初始状态是一个空对象然后需要初始化.正确?
  2. 初始化是异步的,只能在页面加载后发生,我猜想.这可能就是为什么我的代码不起作用的原因!?

我试过以下:

制作了一个mapboxmap模块

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
}
Run Code Online (Sandbox Code Playgroud)

作为组成部分:

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>
Run Code Online (Sandbox Code Playgroud)

哪个不起作用.任何有关解决方案方法的建议和具体的方法都非常感谢.

我在浏览器中收到的错误消息:

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
Run Code Online (Sandbox Code Playgroud)

编辑:更改为this.myMapForViewthis.computed.myMapForView我在浏览器中得到以下errormessage:

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
Run Code Online (Sandbox Code Playgroud)

Sau*_*abh 4

在我看来这new mapboxgl.Map()是一个异步函数,在vuex中 Actions可以包含任意异步操作,而不是突变,而不是来自突变突变处理函数必须是同步的。

所以你应该采取new mapboxgl.Map()如下行动:

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
}
Run Code Online (Sandbox Code Playgroud)

编辑

鉴于您的鼠标交互导致状态发生变化,您可以在 vue 实例中使用getter 和 setter拥有一个计算属性,如下所示:

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

工作小提琴:http://jsfiddle.net/aucqteLn/

另请检查:带有“strict: true”的 Vuex 存储不起作用