我刚刚开始将vuex与vue结合使用。我(大致)了解文档。我有一个特定的问题,我不确定是否应该使用vuex,以及如何使用。

我有一个应用,其中mapbox map 在各种布局和组件等中无处不在。由于我将制作多个vue单个文件组件,但正在使用mapbox map 的一个相同实例,所以我认为拥有mapbox是有意义的在vuex存储中启动和管理的 map 。所以当我更改 map 布局或其他内容时,它将反射(reflect)在所有组件中。

当我继续朝着这个方向前进时,我会为以下几件事感到困惑:

  • 该映射不仅是变量/数组,而且是mapbox类映射的实例。因此,我假设初始状态是一个空对象,然后需要对其进行初始化。正确的?
  • 我想初始化是异步的,只能在页面加载后发生。这可能就是为什么我的以下代码无法正常工作!?

  • 我尝试了以下操作:

    制作了一个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
    }
    

    并作为组件:

    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>
    

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

    我在浏览器中收到错误消息:
    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
    

    编辑:
    this.myMapForView更改为this.computed.myMapForView后,我在浏览器中收到以下错误消息:
    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
    

    最佳答案

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

    因此,您应该在类似以下的操作中执行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
    }
    

    编辑:

    考虑到您的鼠标交互导致状态发生变化,您可以在vue实例中使用computed property带有一个getter and setter,如下所示:
    computed: {
      myMapForView: {
        // getter
        get: function () {
          return this.$store.state. myMap
        },
        // setter
        set: function (newMap) {
          this.$store.commit('loadMap', newMap)
        }
      }
    }
    

    工作 fiddle :http://jsfiddle.net/aucqteLn/

    还要检查:Vuex store with "strict: true" does not work

    关于vue.js - 如何在Vuex中为 map 框 map 设置集中式状态?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41308177/

    10-12 14:04