根据openlayers官方的popup实例改的,使用Vue2+TS,功能比较简单
OLPopop.vue
<template>
<div ref="container" class="ol-popup">
<a href="#" ref="closer" class="ol-popup-closer"></a>
<slot></slot>
</div>
</template>
import Overlay from "ol/Overlay";
import { Component, Vue, Ref } from "vue-property-decorator";
@Component
export default class OLPopup extends Vue {
@Ref("container") container!: HTMLDivElement;
@Ref("closer") closer!: HTMLDivElement;
overlay = new Overlay({});
private mounted() {
this.overlay = new Overlay({
element: this.container,
autoPan: {
animation: {
duration: 250,
},
},
});
this.closer.onclick = () => {
this.overlay.setPosition(undefined);
this.closer.blur();
return;
};
}
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
调用
HelloWorld.vue
<template>
<div class="main">
<div id="map" class="map"></div>
<OLPopup ref="olPopup">
<div>
<p>You clicked here:</p>
<code>{{ info }}</code>
</div>
</OLPopup>
</div>
</template>
import "ol/ol.css";
import Map from "ol/Map";
import TileLayer from "ol/layer/Tile";
import View from "ol/View";
import OSM from "ol/source/OSM";
import { toLonLat } from "ol/proj";
import { toStringHDMS } from "ol/coordinate";
import { Component, Vue, Ref } from "vue-property-decorator";
import OLPopup from "../widgets/OLPopop.vue";
@Component({ components: { OLPopup } })
export default class HelloWorld extends Vue {
private info: string = "";
@Ref("olPopup") myPopup!: OLPopup;
private mounted() {
const map = new Map({
layers: [
new TileLayer({
source: new OSM(),
}),
],
target: "map",
view: new View({
center: [0, 0],
zoom: 2,
}),
});
map.addOverlay(this.myPopup.overlay);
map.on("singleclick", (evt) => {
const coordinate = evt.coordinate;
const hdms = toStringHDMS(toLonLat(coordinate));
this.info = hdms;
this.myPopup.overlay.setPosition(coordinate);
});
}
}
.main {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
overflow: hidden;
}
.map {
width: 100%;
height: 100%;
}
效果
感觉还算简练,样式可以再优化一下,下次试一下插槽支不支持elementui的表格之类的