我有一个mapbox地图,用outdoors-v9样式初始化(尝试了其他样式,相同的行为)。当我向地图添加图层 - 标记或geojson源并缩放地图,样式更改或中断时,我不确定哪一个。
这是启动地图和添加标记的功能
mapboxgl.accessToken = "pk.*******";
buildMap: function() {
const _self = this;
_self.map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/outdoors-v9",
center: [-95.712891, 37.09024],
zoom: 3
});
_self.map.on('load', function() {
_self.map.addSource('route', {
'type': 'geojson',
'data': {
"type": "FeatureCollection",
"features": []
}
});
_self.map.addLayer({
'id': 'route',
'source': 'route',
'type': 'line',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#47576A',
'line-width': 3
}
});
});
}
...
const coords = [addressData.longitude, addressData.latitude];
const marker = new mapboxgl.Marker().setLngLat(coords).addTo(this.map);
我正在使用Vue.js来渲染地图。 Mapbox版本v0.45.0
非常感谢任何帮助或潜在客户
答案 0 :(得分:1)
似乎问题与我将标记实例推送到observable(vuejs数据字段)的事实有关。将标记实例推送到数组后,问题就消失了。这个评论并没有真正回答为什么会发生这种情况,但希望它可以帮助其他可能面临同样问题的人
答案 1 :(得分:1)
Vue的data()
属性是反应性的,它们分别具有getters
和setters
,因此,在加载地图对象或添加矢量切片图层(geojson)时,Vue会尝试将getter和setter添加到map
和map.layers
会导致vue和vue-dev-tools崩溃并弄乱地图。
如果启用任何栅格图层,则将成功运行,因为栅格图块是通过mapbox.css加载的,而矢量图块是geojson,则已添加到map
对象中。
最简单的解决方案是在vue中定义一个非反应变量,然后在各处重复使用它。
答案 2 :(得分:1)
我只是面对这个问题,并且意识到我并没有完全按照所描述的文档进行操作(跳过了正确的阅读而直接进入了编码)。并且文档说:
存储地图对象
请注意,通常添加到Vuex或组件的 除了原始类型和普通对象之外,任何数据都可以。 Vue添加吸气剂 和每个属性的设置器,所以如果您将Map对象添加到Vuex商店 或组件数据,可能会导致奇怪的错误。如果要存储地图 对象,将其存储为非反应性属性,如下例所示。
问题是我还在Vue组件的“数据”对象内注册了“地图”。但是在示例代码中,它没有在数据中声明,仅在“创建”函数中声明。
https://soal.github.io/vue-mapbox/guide/basemap.html#map-loading
答案 3 :(得分:0)
我有同样的错误。 如果您将地图或标记放在反应性vue.js实例上,则会发生这种情况。
答案 4 :(得分:0)
花了几个小时解决这个问题之后,这是我可以从商店访问地图实例的有效解决方案(感谢https://github.com/vuejs/vue/issues/2637#issuecomment-331913620):
const state = reactive({
map: Object.freeze({ wrapper: /* PUT THE MAP INSTANCE HERE */ });
});
以下是Vue Composition Api的示例:
index.js
import { reactive, computed } from "@vue/composition-api";
export const state = reactive({
map: null
});
export const setMap = (map) => {
state.map = Object.freeze({ wrapper: map});
};
export const getMap = computed(() => state.map.wrapper);
export const initMap = (event) => {
setMap(event.map);
// now you can access to map instance from the "getMap" getter!
getMap.value.addSource("satellite-source", {
type: "raster",
url: "mapbox://mapbox.satellite",
});
getMap.value.addLayer({
id: "satellite-layer",
type: "raster",
source: "satellite-source"
});
};
App.vue
<template>
<MglMap :accessToken="..." :mapStyle="..." @load="onMapLoaded" />
</template>
<script>
import { defineComponent } from "@vue/composition-api";
import { MglMap } from "vue-mapbox";
import { initMap } from "./index.js";
export default defineComponent({
components: {
MglMap
},
setup() {
const onMapLoaded = (event) => {
initMap(event);
}
return { onMapLoaded };
}
});
</script>
答案 5 :(得分:0)
简短而快速的回答。
解释类似于@mlb 的回答。因此,您冻结对象以防止地图迷失方向,并且对于对地图执行的任何操作,请使用额外的对象键回调数据,以防万一是“包装器”。
<template><MglMap :accessToken="..." :mapStyle="..." @load="onMapLoaded" /></template>
<script>
methods: {
onMapLoaded(event) {
this.mapboxEvent = Object.freeze({wrapper: event.map});
},
panMap(event) {
this.mapboxEvent.wrapper.panTo([lng, lat], {duration: 1000, zoom: 14});
}
}
</script>