如何在 Vuex 中为 mapbox 地图设置集中状态?
How to setup a centralized state for a mapbox map in Vuex?
我刚开始使用 vuex 和 vue。我确实(大致)了解文档。我有一个具体的问题,我不确定我是否应该使用 vuex,如果是的话该怎么做。
我有一个应用程序,其中 mapbox 地图在各种布局和组件等中无所不在。因为我将制作几个 vue 单文件组件,但正在使用一个相同的 mapbox 地图实例,我认为它使得在 vuex 存储中启动和管理 mapbox 地图是有意义的。所以例如当我更改地图布局或其他内容时,它会反映在所有组件中。
当我继续朝这个方向前进时,我对一些事情感到困惑:
- 地图不只是一个变量/数组,而是 mapbox class 地图的一个实例。所以我假设初始状态是一个空对象,然后需要对其进行初始化。正确吗?
- 我想初始化是异步的,只能在页面加载后发生。这可能就是我下面的代码不起作用的原因!?
我试过以下方法:
制作了一个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.computed.myMapForView
更改为 this.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 can contain arbitrary asynchronous operations not mutations not from 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
}
编辑:
鉴于您的鼠标交互导致状态发生变化,您可以computed property in you vue instance with 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 和 vue。我确实(大致)了解文档。我有一个具体的问题,我不确定我是否应该使用 vuex,如果是的话该怎么做。
我有一个应用程序,其中 mapbox 地图在各种布局和组件等中无所不在。因为我将制作几个 vue 单文件组件,但正在使用一个相同的 mapbox 地图实例,我认为它使得在 vuex 存储中启动和管理 mapbox 地图是有意义的。所以例如当我更改地图布局或其他内容时,它会反映在所有组件中。
当我继续朝这个方向前进时,我对一些事情感到困惑:
- 地图不只是一个变量/数组,而是 mapbox class 地图的一个实例。所以我假设初始状态是一个空对象,然后需要对其进行初始化。正确吗?
- 我想初始化是异步的,只能在页面加载后发生。这可能就是我下面的代码不起作用的原因!?
我试过以下方法:
制作了一个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.computed.myMapForView
更改为 this.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 can contain arbitrary asynchronous operations not mutations not from 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
}
编辑:
鉴于您的鼠标交互导致状态发生变化,您可以computed property in you vue instance with 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/
同时检查: