这个问题非常非常的奇怪,如下面写的一个vue组件,slot中是具体的信息弹窗的内容,里面有一个关闭按钮,点击关闭按钮之后,我想着父元素通过监听 popup_close 事件,进行popup的销毁操作,于是我需要一个引用,就是使用curPopup 这个变量,引用 new mapboxgl.Popup 生成的popup对象,当点击关闭的时候,就执行 closePopup 方法,使用 this.curPopup.remove(); 移除这个弹出框,这样的逻辑没有问题吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| <template> <div class="soli-popup"> <slot></slot> </div> </template>
<script> import centroid from "@turf/centroid";
export default { data(){ return { curPopup:null } }, computed: { curFeature() { return this.$store.state.soli.curFeature }, }, mounted() { this.render(); this.$bus.$on("popup_close",this.closePopup); }, watch: { curFeature() { this.render(); }, }, methods: { render() { let map=window.glMap; if (!map) { return; }
let p = centroid(this.curFeature); let coordinates=p.geometry.coordinates; let popup =new mapboxgl.Popup({ closeButton: false, closeOnClick:false }) .setLngLat(coordinates) .setDOMContent(this.$el) .setMaxWidth(360) .addTo(map);
popup.on("close", () => { this.$store.commit("soli/curFeature_changed"); });
}, closePopup(){ this.curPopup.remove(); } }, destroy(){ console.log("销毁"); } }; </script>
|
问题就出现在了这个 this.curPopup=popup 引用上,我 render 函数中,将它注释掉,点击的时候是没有问题的,但是当我去掉注释,引用这个变量的时候,点击时就出现了问题。正常的点击时这样的:
不正常的点击,点击之后,点位的样式就变化了,而且出现了一个境界线的黑色,水系的颜色也变化了。
刚开始,我也以为是因为点击操作时进行了其他的操作,但是最后,经过两三天的调试、修改变量名字,减少绘图图层的数量,精简代码,最后,就是这一个变量引用导致的问题,我真是蛋疼的要死啊。
【解决办法】
问题出现的非常诡异,解决起来也是非常的诡异,不能绑定到this上,我绑定到了windows上,竟然成功了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| import centroid from "@turf/centroid";
export default { data(){ return { } }, computed: { curFeature() { return this.$store.state.soli.curFeature }, }, mounted() { this.render(true); }, watch: { curFeature() { this.render(true); }, }, methods: { render() { let map=window.glMap; if (!map) { return; } let p = centroid(this.curFeature); let coordinates=p.geometry.coordinates; let popup =new mapboxgl.Popup({ closeButton: false, closeOnClick:false }) popup.setLngLat(coordinates) .setDOMContent(this.$el) .setMaxWidth(360) .addTo(map);
window.curSoliPopup=popup; popup.on("close", () => { this.$store.commit("soli/curFeature_changed"); }); } }, beforeDestroy(){ console.log("dds"); let popup=window.curSoliPopup; if(popup){ popup.remove(); } delete window.curSoliPopup; } };
|
2.code= internalerror rendering process failed
在使用mapbox调用自己发布的地图时,出现了这个问题。因为这个请求涉及到了geoserver、mapserver,还有可能是自定义的切片mvt,所以不太清楚这个问题出现的原因到底是什么,需要一点点的排查。
在多数的资料中,显示的是geoserver问题比较多,但是这个问题也很难排查,主要是因为不清楚到底是哪个日志导致的。
3.无法使用引用
我遇到了一个奇怪的问题,就是在保存 marker 的引用的时候,两种写法会出现不一样的问题。第一种写法,在保存引用之后,整个页面就会变成黄色,也就是导致整个地图变化。
1 2 3 4 5 6
| marker = new mapboxgl.Marker(el) marker.setLngLat(coordinates) marker.addTo(map)
this.pinMarker = marker
|
但是第二种写法就没有问题,这个问题叫我百思不解,到底因为什么呢?
1 2 3 4 5 6
| marker = new mapboxgl.Marker(el)
this.pinMarker = marker marker.setLngLat(coordinates) marker.addTo(map)
|
4.生成的dom无法挂载到ducument上
这个问题我无法理解,甚至都不知道该如何描述,就是我在 popup 中绑定的事件,和在其他地方绑定的事件,效果出现的不一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| <template lang="pug"> .infowindow .close(@click="closeInfowindow") i.el-icon-close .info-item .info-label 设备名称 .info-content {{ drone.nickname }} .info-item .info-label 设备地址 .info-content {{ drone.address }} .info-item .info-label 设备状态 .info-content(:class="[drone.status?'info-green':'info-red']") {{ drone.status?"在线":"离线" }} .info-btn(@click="showDroneLive") 设备详情
</template> <script> export default { name: 'drone-infowindow', data() { return { drone: null, infowindow: null // 弹出框 } }, mounted() { // 设备定位 this.$bus.$on('device_location', this.showInfowindow) }, methods: { // 显示信息框 showInfowindow(drone) { let gateway_sn = drone.gateway_sn let drone_sn = drone.drone_sn this.drone = drone // 显示面板 let map = window.glMap let coordinates = [drone.lon, drone.lat] window.glPopup = new mapboxgl.Popup({ closeButton: false, className: 'drone-info', closeOnClick: false }) .setLngLat(coordinates) .setDOMContent(this.$el) .addTo(map) }, // 关闭信息框 closeInfowindow() { if (window.glPopup) { window.glPopup.remove() } }, // 就是这个函数,创建的dom,就是挂不到页面上去,无法在 v-for 上使用 showDroneLive() { this.$bus.$emit('showDroneLive', this.drone) } }, beforeDestroy() { this.closeInfowindow() } } </script> <style lang="stylus" scoped> .infowindow position relative width 250px padding 24px color: #fff !important; font-family: Microsoft YaHei !important; font-size 16px .close position absolute right 10px top 10px cursor pointer
.info-item margin-bottom 10px display flex .info-label width 80px
.info-red color red .info-green color green
.info-btn padding 5px 10px cursor pointer background rgba(0, 193, 100, 1) border-radius 5px text-align center </style> <style lang="stylus"> .drone-info max-width initial!important .mapboxgl-popup-content padding 0 !important background-color rgba(4, 26, 34, 0.9)!important border-radius 12px .mapboxgl-popup-tip border-bottom-color rgba(4, 26, 34, 0.9)!important border-top-color rgba(4, 26, 34, 0.9)!important </style>
|
上面是一个 popup 弹出框,下面是一个响应的 v-for
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| <template lang="pug"> .flightmonitoring(v-if="showPanel") RightPanel LeftPanel DroneLiveDialog(v-for="item in droneLives" :key="item.device_sn" v-bind:drone="item") {{ droneLives.length }} InfoWindow </template> <script> import apiMixin from './flightMonitoring/mixins/apiMixin' export default { name: 'flightmonitoring', mixins: [apiMixin], components: { RightPanel: () => import('./flightMonitoring/RightPanel'), LeftPanel: () => import('./flightMonitoring/LeftPanel'), DroneLiveDialog: () => import('./flightMonitoring/LiveDialog.vue'), // 无人机驾驶舱 InfoWindow: () => import('./flightMonitoring/InfoWindow.vue') // 信息弹窗 }, data() { return { userAuthority: 0, // 用户信息 showPanel: false, // 是否显示面板 droneLives: [] // 无人机列表 } }, mounted() { // 显示无人机面板 this.$bus.$on('showDroneLive', item => { let count = this.droneLives.length let flag = false // 是否存在,避免重复添加 for (let i = count - 1; i >= 0; i--) { let temp = this.droneLives[i] let id = temp.device_sn if (id == item.device_sn) { flag = true break } } if (!flag) { this.droneLives.push(item) } }) // 关闭无人机面板 this.$bus.$on('closeDroneLive', item => { let count = this.droneLives.length for (let i = 0; i < count; i++) { let temp = this.droneLives[i] let id = temp.device_sn if (id == item.device_sn) { this.droneLives.splice(i, 1) i-- break } } }) }, methods: { }, beforeDestroy() { // 卸载 let map = window.glMap if (map && map.getSource('flyable_area')) { map.removeLayer('flyable_area') map.removeSource('flyable_area') } } } </script>
|
问题就特别的奇怪,就是如果 InfoWindow 放到 DroneLiveDialog 之后,那么这个 DroneLiveDialog 就死活是显示不了
1 2 3 4 5 6 7
| <template lang="pug"> .flightmonitoring(v-if="showPanel") RightPanel LeftPanel DroneLiveDialog(v-for="item in droneLives" :key="item.device_sn" v-bind:drone="item") {{ droneLives.length }} InfoWindow </template>
|
但是如果 InfoWindow 放到 DroneLiveDialog 之前,那么这个 DroneLiveDialog 就可以弹出来了。真是操蛋的玩意,我终于知道,为什么写代码叫做玄学了,真是无法合理的解释这个东西啊。
1 2 3 4 5 6 7
| <template lang="pug"> .flightmonitoring(v-if="showPanel") RightPanel LeftPanel InfoWindow DroneLiveDialog(v-for="item in droneLives" :key="item.device_sn" v-bind:drone="item") {{ droneLives.length }} </template>
|