uniapp微信小程序地图多地点标记组件
已关注
关注
重播 分享 赞

<map class="map" id="map":show-location="true"theme="satellite":markers="listMarkers":scale="state.scale":latitude="state.latitude":longitude="state.longitude":min-scale="state.minScale"@regionchange="mapRegionchange"@callouttap="markertap"@markertap="markertap"></map>
const state = reactive({// 默认位置坐标-或者获取当前设备的坐标赋值latitude: 28.668148, //初始默认中心纬度longitude: 115.866537, //初始默认中心经度scale: 13, //初始缩放大小 数字越小 显示的范围越大,数字越大显示的范围越少 最大18minScale: 4.5, //最小缩放级别// 地图标点markers: [],// 列表标记点数据listMarkers: [],}); //地图属性

2、实现地图的操作:放大缩小,返回当前位置<!--地图操作按钮--><viewclass="map-btn"><!-- 按钮-返回原位 --><viewclass="tool-btn" @tap="toLocation"><textclass="nvue-iconfont mapico"></text></view><!-- 按钮-放大 --><viewclass="tool-btn" @tap="mapScaleUp"><textclass="nvue-iconfont mapico"></text></view><!-- 按钮-缩小 --><viewclass="tool-btn" @tap="mapScaleDown"><textclass="nvue-iconfont mapico"></text></view></view>
// 回到原位/我的位置,恢复默认缩放const toLocation = () => {//移动到当前的坐标_mapContext.value.moveToLocation({longitude: myLocation.value.longitude,latitude: myLocation.value.latitude});};// 放大地图const mapScaleUp = () => {updateMapScale(1);};// 缩小地图const mapScaleDown = () => {updateMapScale(2);};//设置地图缩放等级const updateMapScale = (type = 0, level = 15) => {_mapContext.value.getScale({success: res => {state.scale = res.scale;nextTick(() => {// 指定缩放级别if (type == 0) {state.scale = level}// 放大else if (type == 1 && state.scale < 20) {state.scale = state.scale + 1 > 20 ? 20 : state.scale + 1}// 缩小else if (type == 2 && state.scale > state.minScale) {state.scale = state.scale - 1 < state.minScale ? state.minScale : state.scale - 1}})}})};
如图:

{id:1,longitude:'115.851002', //经度latitude:'28.689684',//纬度iconPath:'/static/ad/ad01.jpg',//缩略图width:40,height: 40,title:'商家1',address:'商家标记地址1',alpha: 1, //透明度callout: { //自定义标记点上方的气泡窗口 点击有效content: '商家标记点1',//文本color: '#ffffff',//文字颜色fontSize: 12,//文本大小borderRadius: 5,//边框圆角padding:7,bgColor: '#ff6100',//背景颜色display: 'ALWAYS',//常显},}

// 点击地图marker点const markertap = (e) => {//获取选中的信息const value = listMarkers.value.find(item => item.id == e.detail.markerId); //查找符合的信息chooseItemInfo.value = value;emits("chooseMarker", value); //传输通知给父组件};
<!--选中的信息底部漂浮框--><viewclass="info-view"v-if="chooseItemInfo.id"><viewclass="iv-item"><imageclass="ivi-img":src="chooseItemInfo.iconPath"mode="widthFix" /><viewclass="ivi-text"><textclass="ivi-t-title">{{ chooseItemInfo.title }}</text><textclass="ivi-t-address">{{ chooseItemInfo.address }}</text></view></view></view>
5、地图视野发生变化时,显示当前视野内的标记点
// 地图视野发生变化const mapRegionchange = (e) => {// console.log(e,"视野发生变化时触发",_mapContext.value.getCenterLocation());chooseItemInfo.value = {};//移动结束时 加载范围内的列表的数据if (e.type === "end") {//地图移动结束后 获取中心的的坐标(可发送给后台处理 获取范围内的数据,更新标记)_mapContext.value.getCenterLocation({success(res) {//获取移动结束时的const latitude = res.latitudeconst longitude = res.longitudeif ((state.longitude - longitude) < 0.000005 && (state.longitude - longitude) > 0 &&latitude == state.latitude) { // 对静态移动标点做限制防止偏移return}emits("moveMapView", res); //传输移动到的中心坐标// console.log('地图视野变化');state.latitude = res.latitude;state.longitude = res.longitude;// nextTick(() => {// getList();// })}})}};
https://uniapp.dcloud.net.cn/component/map.html
<template><!--腾讯地图多标记点组件--><viewclass="map-box"><!--地图主体--><viewclass="map-viw"><mapclass="map"id="map":show-location="true"theme="satellite":markers="listMarkers":scale="state.scale" :latitude="state.latitude" :longitude="state.longitude" :min-scale="state.minScale"@regionchange="mapRegionchange" @callouttap="markertap" @markertap="markertap"></map></view><!--地图操作按钮--><viewclass="map-btn"><!-- 按钮-返回原位 --><viewclass="tool-btn" @tap="toLocation"><textclass="nvue-iconfont mapico"></text></view><!-- 按钮-放大 --><viewclass="tool-btn" @tap="mapScaleUp"><textclass="nvue-iconfont mapico"></text></view><!-- 按钮-缩小 --><viewclass="tool-btn" @tap="mapScaleDown"><textclass="nvue-iconfont mapico"></text></view></view><!--选中的信息底部漂浮框--><viewclass="info-view"v-if="chooseItemInfo.id"><viewclass="iv-item"><imageclass="ivi-img":src="chooseItemInfo.iconPath"mode="widthFix" /><viewclass="ivi-text"><textclass="ivi-t-title">{{ chooseItemInfo.title }}</text><textclass="ivi-t-address">{{ chooseItemInfo.address }}</text></view></view></view></view></template><scriptsetup>import {ref,reactive,nextTick,getCurrentInstance,watch} from 'vue'import {onReady} from "@dcloudio/uni-app";//宏命令-自动暴露声明const props = defineProps({markersArr: {type: Array,default:()=>{return []},}, //标记点列表myLcat: {type: Object,default: ()=>{return {}}}, //我的位置});const _mapContext = ref(null); //地图对象onReady(() => {console.log("onReady");_mapContext.value = uni.createMapContext('map',getCurrentInstance()); //getCurrentInstance为当前的组件实例对象,如vue2中的this});const listMarkers = ref(props.markersArr); //地图标记点const chooseItemInfo = ref({}); //点击mark选中的信息const myLocation = ref(props.myLcat); //我的中心点位置const state = reactive({// 默认位置坐标-或者获取当前设备的坐标赋值latitude: 28.668148, //初始默认中心纬度longitude: 115.866537, //初始默认中心经度scale: 13, //初始缩放大小 数字越小 显示的范围越大,数字越大显示的范围越少 最大18minScale: 4.5, //最小缩放级别// 地图标点markers: [],// 列表标记点数据listMarkers: [],}); //地图属性//监听标记数据的变化const mr = watch(() => props.markersArr, (newVal) => {// console.log(newVal,"数据")listMarkers.value = newVal;}, {immediate: true // 立即执行初始化})//监听我的位置变化const mc = watch(() => props.myLcat, (newVal) => {// console.log(newVal,"数据");myLocation.value = newVal;}, {immediate: true // 立即执行初始化});const emits = defineEmits(["moveMapView", "chooseMarker"]); //子组件触发通知给父组件的函数方法 地图移动 选中Makers标点// 点击地图marker点const markertap = (e) => {// console.log(e,"点击了marker 点")//获取选中的信息const value = listMarkers.value.find(item => item.id == e.detail.markerId); //查找符合的信息chooseItemInfo.value = value;emits("chooseMarker", value); //传输通知给父组件};// 回到原位/我的位置,恢复默认缩放const toLocation = () => {//移动到当前的坐标_mapContext.value.moveToLocation({longitude: myLocation.value.longitude,latitude: myLocation.value.latitude});};// 放大地图const mapScaleUp = () => {updateMapScale(1);};// 缩小地图const mapScaleDown = () => {updateMapScale(2);};//设置地图缩放等级const updateMapScale = (type = 0, level = 15) => {_mapContext.value.getScale({success: res => {state.scale = res.scale;nextTick(() => {// 指定缩放级别if (type == 0) {state.scale = level}// 放大else if (type == 1 && state.scale < 20) {state.scale = state.scale + 1 > 20 ? 20 : state.scale + 1}// 缩小else if (type == 2 && state.scale > state.minScale) {state.scale = state.scale - 1 < state.minScale ? state.minScale : state.scale - 1}})}})};// 地图视野发生变化const mapRegionchange = (e) => {// console.log(e,"视野发生变化时触发",_mapContext.value.getCenterLocation());chooseItemInfo.value = {};//移动结束时 加载范围内的列表的数据if (e.type === "end") {//地图移动结束后 获取中心的的坐标(可发送给后台处理 获取范围内的数据,更新标记)_mapContext.value.getCenterLocation({success(res) {//获取移动结束时的const latitude = res.latitudeconst longitude = res.longitudeif ((state.longitude - longitude) < 0.000005 && (state.longitude - longitude) > 0 &&latitude == state.latitude) { // 对静态移动标点做限制防止偏移return}emits("moveMapView", res); //传输移动到的中心坐标// console.log('地图视野变化');state.latitude = res.latitude;state.longitude = res.longitude;// nextTick(() => {// getList();// })}})}};</script><stylelang="scss">@font-face {font-family: 'mapico';src: url('./iconfont.ttf') format('truetype');}/**ioc 图标**/.mapico {font-family: mapico;/* font-size: 70upx; */}.map-box {width: 100vw;height: 100vh;overflow: hidden;display: flex;flex-direction: column;.map-viw {width: 100%;height: 100%;flex: 2;display: flex;flex-direction: column;overflow: hidden;.map {width: 100%;height: 100%;position: relative;}}// 右侧按钮组.map-btn {width: 70rpx;height: 70rpx;position: fixed;right: 30rpx;top: 50rpx;.tool-btn {background-color:#ffffff;border-radius: 10rpx;width: 70rpx;height: 70rpx;align-items: center;justify-content: center;box-shadow: 0 0 8px#ccc;margin-bottom: 20rpx;.nvue-iconfont {display: block;position: relative;text-align: center;line-height: 76rpx;color:#333;font-size: 44rpx;}}}//信息.info-view {position: absolute;z-index: 2;width: 100%;height: 140rpx;bottom: 100rpx;left: 0;display: flex;justify-content: center;.iv-item {width: 80%;background-color:#ffffff;padding: 10rpx;height: 100%;border-radius: 10rpx;display: flex;flex-direction: row;align-items: center;.ivi-img {padding: 10rpx;width: 120rpx;height: 120rpx;}.ivi-text {flex: 2;display: flex;flex-direction: column;.ivi-t-title {font-size: 1rem;font-weight: bold;color:#333;}.ivi-t-address {font-size: 0.8rem;color:#999;}}}}}</style>
引用组件,所使用测试数据为静态数据:<template><!--腾讯地图插件--><mapViewv-if="isShow":markersArr="markerArr":myLcat="myLocation" @chooseMarker="getChooseMarker" @moveMapView="getMapCenterLoca"></mapView></template><scriptsetup>import { nextTick, onMounted, ref } from 'vue';import mapView from '@/components/map/map.vue'const markerArr = ref([]);//标记点,可动态获取const isShow = ref(false);//const myLocation = ref({});//用户发送到后台请求对应的数据onMounted(()=>{getMapMarkersList();nextTick(()=>{isShow.value = true;})getMyLocation();});//获取地图移动的中心坐标const getMapCenterLoca = (e)=>{console.log("中心坐标:",e);};//获取选中的标记const getChooseMarker = (e) =>{console.log("选中的气泡标记:",e);};//获取当前所在的位置const getMyLocation =()=>{//获得当前的位置uni.getLocation({type: 'gcj02', //返回国测局坐标success(e) {console.log(e,"我的位置")myLocation.value = e;},fail(e) {console.log('失败', e);}})}//获取位置中心范围内的数据const getMapMarkersList = () =>{// markerArr.value = [];markerArr.value = [{id:1,longitude:'115.851002', //经度latitude:'28.689684',//纬度iconPath:'/static/ad/ad01.jpg',//缩略图width:40,height: 40,title:'商家1',address:'商家标记地址1',alpha: 1, //透明度callout: { //自定义标记点上方的气泡窗口 点击有效content: '商家标记点1',//文本color: '#ffffff',//文字颜色fontSize: 12,//文本大小borderRadius: 5,//边框圆角padding:7,bgColor: '#ff6100',//背景颜色display: 'ALWAYS',//常显},},{id:2,longitude:'115.880356',latitude:'28.643896',iconPath:'/static/ad/ad02.jpg',width:40,height: 40,title:'商家2',address:'商家标记地址2',alpha: 1,callout: { //气泡窗口content:'商家标记点2',color: '#ffffff',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#ffaa00',display: 'ALWAYS',},},{id:3,longitude:'115.902672',latitude:'28.671311',iconPath:'/static/ad/ad03.jpg',width:40,height: 40,title:'商家3',address:'商家标记地址3',alpha: 1,callout: { //气泡窗口content: '商家标记点3',color: '#ffffff',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#3f94fd',display: 'ALWAYS',},},{id:4,longitude:'115.881386',latitude:'28.682456',iconPath:'/static/ad/ad02.jpg',width:40,height: 40,title:'商家4',address:'商家标记地址4',alpha: 1,callout: { //气泡窗口content: '商家标记点4',color: '#000000',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#00ff00',display: 'ALWAYS',},},{id:5,longitude:'115.854435',latitude:'28.677787',iconPath:'/static/ad/ad01.jpg',width:40,height: 40,title:'商家5',address:'商家标记地址5',alpha: 1,callout: { //气泡窗口content: '商家标记点5',color: '#ffffff',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#3f94fd',display: 'ALWAYS',},},{id:6,longitude:'115.848255',latitude:'28.660617',iconPath:'/static/ad/ad02.jpg',width:40,height: 40,title:'商家6',address:'商家标记地址6',alpha: 1,callout: { //气泡窗口content: '商家标记点6',color: '#3f94fd',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#ffffff',display: 'ALWAYS',},},{id:7,longitude:'115.849972',latitude:'28.670407',iconPath:'/static/ad/ad03.jpg',width:40,height: 40,title:'商家7',address:'商家标记地址7',alpha: 1,callout: { //气泡窗口content: '商家标记点7',color: '#ffffff',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#3f94fd',display: 'ALWAYS',},},{id:8,longitude:'115.900612',latitude:'28.661671',iconPath:'/static/ad/ad01.jpg',width:40,height: 40,title:'商家8',address:'商家标记地址8',alpha: 1,callout: { //气泡窗口content: '商家标记点8',color: '#ffffff',fontSize: 12,borderRadius: 5,padding:7,bgColor: '#3f94fd',display: 'ALWAYS',},},];}</script><style></style>
夜雨聆风