Javascript 添加图层时,缩放时贴图框样式会更改/中断
我有一个mapbox映射,用outdoors-v9样式初始化(尝试了其他样式,相同的行为)。当我向地图添加一个图层(标记或geojson源)并缩放地图时,样式会改变或中断,我不确定是哪一个 这是缩放前的地图 变焦之后呢 以下是初始化映射和添加标记的函数Javascript 添加图层时,缩放时贴图框样式会更改/中断,javascript,vue.js,mapbox,mapbox-marker,Javascript,Vue.js,Mapbox,Mapbox Marker,我有一个mapbox映射,用outdoors-v9样式初始化(尝试了其他样式,相同的行为)。当我向地图添加一个图层(标记或geojson源)并缩放地图时,样式会改变或中断,我不确定是哪一个 这是缩放前的地图 变焦之后呢 以下是初始化映射和添加标记的函数 mapboxgl.accessToken = "pk.*******"; buildMap: function() { const _self = this; _self.map = new mapboxgl.Map({
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
}
});
});
}
我正在使用Vue.js渲染地图。地图盒版本v0.45.0
非常感谢任何帮助或线索问题似乎与我将marker实例推到可观察的位置(vuejs数据字段)有关。将标记实例推送到数组后,问题消失了。这条评论并不能真正回答为什么会发生这种情况,但希望它能帮助其他可能面临同样问题的人我也有同样的错误。 如果将地图或标记放在反应性vue.js实例上,就会发生这种情况。vue
data()
属性是反应性的,它们具有getter
和setter
,因此,在加载地图对象或添加向量平铺层(geojson)时,Vue尝试将getter和setter添加到映射
&映射层
,这会导致Vue&Vue开发工具崩溃并破坏映射
如果启用任何光栅层,它将成功工作,因为光栅图块是通过mapbox.css加载的,而矢量图块是geojson,被添加到map
对象中
最简单的解决方案是在vue中定义一个非反应性变量,然后在任何地方重复使用它
//编辑:设置非反应性数据的正确/推荐方法:我刚刚遇到了这个问题,意识到我没有完全按照文档中描述的那样进行操作(没有正确阅读就直接开始编码)。文件上说: 存储地图对象 请注意,添加到Vuex或组件的 除了基本类型和普通对象之外,任何数据都可以。Vue添加了getter 和每个属性的setter,所以如果将Map对象添加到Vuex存储 或者组件数据,它可能会导致奇怪的错误。如果你想储存地图 对象,将其存储为非反应性属性,如下面的示例所示 问题是,我还在Vue组件的“数据”对象中注册了“映射”。但在示例代码中,它不是在数据中声明的,而是在“create”函数中声明的
在花了数小时解决此问题后,以下是我从商店访问地图实例的工作解决方案(感谢):
const state=无功({
map:Object.freeze({wrapper:/*将映射实例放在这里*/});
});
以下是Vue Composition Api的一个示例:
index.js
import{reactive,computed}来自“@vue/compositionapi”;
导出常量状态=无功({
映射:空
});
导出常量setMap=(map)=>{
state.map=Object.freeze({wrapper:map});
};
export const getMap=computed(()=>state.map.wrapper);
导出常量initMap=(事件)=>{
setMap(event.map);
//现在您可以从“getMap”getter访问map实例了!
getMap.value.addSource(“卫星源”{
键入:“光栅”,
url:“mapbox://mapbox.satellite",
});
getMap.value.addLayer({
id:“卫星层”,
键入:“光栅”,
资料来源:“卫星来源”
});
};
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>
从“@vue/composition api”导入{defineComponent};
从“vue映射框”导入{MglMap};
从“/index.js”导入{initMap};
导出默认定义组件({
组成部分:{
MglMap
},
设置(){
加载时常量=(事件)=>{
initMap(事件);
}
返回{onmapploaded};
}
});
简短快速的回答
解释与@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>
方法:{
加载时(事件){
this.mapboxEvent=Object.freeze({wrapper:event.map});
},
全景图(事件){
panTo([lng,lat],{duration:1000,zoom:14});
}
}
Small update,似乎只有当我将标记实例推送到vuejs数据对象时才会出现问题。仍然不知道为什么会发生这种情况在将映射对象写入组件之前,请添加\u isVue=true
:const map=new mapboxgl.map({…});映射。_isVue=true;this.map=map代码>如果你也展示了你的固定代码,这样他们就可以看到是什么解决了这个问题,这对其他人真的很有帮助。只是一个建议。
<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>