uniapp中利用renderjs引入leaflet
由于uniapp中要使用地图,虽然uni-app有地图组件map,但是很难用,而且性能很差。在app中是不能操作dom,所以直接用leaflet是不可能的。最终发现了renderjs,官网提出,在app-vue环境下,视图层由webview渲染,而renderjs运行在视图层,自然可以操作dom和window。
使用注意事项:
:prop 传值 :change:prop 监听prop改变
调用改变的方法内有四个参数
newValue:跟新后的数据
oldValue:原先的数据
ownerInstance:通过该函数可以调用内部函数,可以传输数据
instance:当前service层实例
通过 this.$ownerInstance.$vm 获取当前组件的 ComponentDescriptor 实例
完整示例代码:
<template>
<view class="leafletMap">
<view
class="mapBox"
id="mapId"
:prop="psArr"
:change:prop="leaflet.updatePsArr"
></view>
</view>
</template>
<script>
export default {
data() {
return {
psArr: [], //企业数组
};
},
onLoad() {
this.$nextTick(() => {
this.queryPsGis();
});
},
methods: {
//请求企业gis数据
async queryPsGis() {
this.psArr = []; //重置企业的站点信息
const { data = {} } = await this.$http(
'/smoke/smokeData/getPsRealityDataGis',
'get'
);
if (data.code !== 200) {
return uni.showToast({
title: '请求数据异常',
icon: 'error',
mask: true,
});
}
if (data.result.length > 0) {
this.psArr = data.result.filter(
(item) =>
item.pscode !== null &&
item.pscode !== undefined &&
item.pscode !== ''
); //排除第一个无意义内容
}
},
//renderjs 传递给视图层
getMessage(option) {
uni.showToast({
title: option.text,
icon: 'success',
mask: true,
});
},
},
};
</script>
<script module="leaflet" lang="renderjs">
export default {
data() {
return {
map: null, //地图容器
centerpoint: [37.6211, 114.9304676], //默认中心位置
zoomlevel: 14, //初始化放大倍数
baseLayer: null, //矢量底图
markers:null,
ownerInstance:null,//接收视图层dom
}
},
mounted() {
// 动态引入较大类库避免影响页面展示
const link = document.createElement('link');
link.rel = "stylesheet"
link.href = "https://unpkg.com/leaflet@1.9.3/dist/leaflet.css";
document.head.appendChild(link)
const script = document.createElement('script')
script.src = "https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
script.type = "text/javascript"
script.onload = this.initMap.bind(this)
document.head.appendChild(script)
},
methods: {
initMap() {
this.map = L.map('mapId', {
minZoom: 5,
maxZoom: 18,
crs: L.CRS.EPSG3857,
center: this.centerpoint,
zoom: this.zoomlevel,
fullscreenControl: false,
zoomControl: false,
attributionControl: false,
})
//添加基础图层
this.baseLayer = L.tileLayer(
'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', {
minZoom: 5,
maxZoom: 18,
pane: 'overlayPane',
}
)
this.map.addLayer(this.baseLayer)
},
//属性psArr变化监控
updatePsArr(newValue, oldValue, ownerInstance, instance) {
if(newValue.length>0){
this.ownerInstance = ownerInstance
if(this.markers){
this.map.removeLayer(this.markers)
this.markers = null
}
this.addMarkerCluster(newValue)
}
},
//处理整合geoJSON所需要的marker数据
handlePsGeoJson(arr) {
let coorsField = {
type: 'FeatureCollection',
features: [],
}
arr.forEach((item) => {
let lon = item.lon
let lat = item.lat
if (lon && lat) {
coorsField.features.push({
type: 'Feature',
properties: {},
geometry: {
type: 'Point', // 配合 pointToLayer 一起使用
coordinates: [lon, lat],
},
})
}
})
return coorsField
},
//添加marker标记
addMarkerCluster(arr) {
// 添加站点marker标记
this.markers = L.geoJSON(this.handlePsGeoJson(arr), {
pointToLayer: (feature, latlng) => {
return L.marker(latlng, {
icon: this.getMarkerIcon(),
zIndexOffset: 1000
}) // 添加标记
},
})
this.map.fitBounds(this.markers.getBounds())
this.markers.addTo(this.map)
//renderjs传递给视图层
// this.ownerInstance.callMethod('getMessage', {
// text: '成功'
// })
},
getMarkerIcon() {
let htmlContent = '<div style="width:24px;height:24px;border-radius:50%;background-color:#5ed323"></div>'
let icon = L.divIcon({
html: htmlContent,
className: 'ss',
iconAnchor: [13, 4],
})
return icon
}
}
}
</script>
<style lang="scss" scoped>
.leafletMap {
width: 100%;
height: 100%;
.mapBox {
box-sizing: border-box;
width: 100%;
height: 100vh;
background-color: #042046;
overflow: hidden;
}
}
</style>

浙公网安备 33010602011771号