如何在Vuex中为地图框地图设置集中式状态? [英] How to setup a centralized state for a mapbox map in Vuex?

查看:100
本文介绍了如何在Vuex中为地图框地图设置集中式状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just started using vuex with vue. I do (roughly) understand the docs. I have a specific issue for which I am not sure whether I should use vuex and if so how to go about.

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

I have an app in which mapbox map(s) are omnipresent in various layouts and components etc. As I will be making several vue single file components but are working with one same instance of a mapbox map I think it makes sense to have the mapbox map initiated and managed in the vuex store. So e.g. when I change the map layout or something else, it will be reflected in all components.

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

When I continue in this direction I am puzzled by a couple of things:

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

我尝试了以下操作:

使用

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>

这不起作用.对此解决方案方法和具体方法的任何建议都将不胜感激.

Which does not work. Any suggestions on the solution approach and specific way to do this is much appreciated.

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

Error message I get in the browser:

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

After changing to this.myMapForView from this.computed.myMapForView I got following errormessage in browser:

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 动作可以包含任意异步操作,不是来自突变的突变. 变异处理程序功能必须是同步的.

It seems to me is new mapboxgl.Map() is an asynchronous function and in vuex Actions can contain arbitrary asynchronous operations not mutations not from mutations. mutation handler functions must be synchronous.

因此,您应该在以下操作中执行new mapboxgl.Map():

So you should do new mapboxgl.Map() in actions like following:

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
}


修改:

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

Given your mouse interactions are causing change in the state, you can have a computed property in you vue instance with getter and setter, like following:

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


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

还要检查:具有"strict:true"的Vuex存储;不起作用


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

Also check: Vuex store with "strict: true" does not work

这篇关于如何在Vuex中为地图框地图设置集中式状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆