uni-app map marker 上的自定义气泡 customCallout显示气泡不对
uni-app map marker 上的自定义气泡 customCallout显示气泡不对
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows 10 专业版 | 22H2 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
手机系统:Android
手机系统版本号:Android 16
手机厂商:小米
手机机型:863904075488527
页面类型:vue
vue版本:vue3
打包方式:云端
项目创建方式:HBuilderX
示例代码:
<template>
<view class="pMap">
<!-- -->
<map class="pMap-box"
id="mapContext"
:longitude="mapInstance.longitude"
:latitude="mapInstance.latitude"
:markers="markers"
:polyline="polyline"
:show-location="true"
:scale="mapScale"
:include-points="includePoints"
:polygon="polygon"
:style="{width:windowWidth+'px',height: '500rpx'}">
<cover-view class="pMap-box-callout" slot="callout">
<block v-for="(item,index) in markers" :key="index" >
<cover-view
v-if="item.customCallout"
class="pMap-box-callout-list"
:marker-id="item.id">
<cover-view class="pMap-box-callout-list-item">
<cover-view class="pMap-box-callout-list-item-center">
<cover-view class="pMap-box-callout-list-item-center-tag">
{{index == 0?'发':index == markers.length-1?'收':''}}
</cover-view>
<cover-view class="pMap-box-callout-list-item-center-txt">
{{item.title}}
</cover-view>
</cover-view>
</cover-view>
</cover-view>
</block>
</cover-view>
</map>
</view>
</template>
<script setup>
import startIcon from '@/static/image/order/map.png'
import processIcon from '@/static/image/order/car.png'
import {ref,getCurrentInstance,computed,defineExpose,onMounted, nextTick} from 'vue';
import {Config} from "@/http/config";
import {systemStore} from '@/store/system'
const {windowWidth} = systemStore();
const _this = getCurrentInstance();
const mapContext = ref(null);
onMounted(()=>{
mapContext.value = uni.createMapContext('mapContext',_this);
})
const props = defineProps({
routePoints: {
type: Array,
default: []
}
})
// 获取标记点图标
const getMarkerIconByStatus = (status) => {
switch (status) {
case 'start':
return startIcon;
case 'end':
return startIcon;
case 'process':
// return null;
return processIcon;
default:
return startIcon;
}
}
// 缓存节点颜色配置
const statusColorMap =(status)=> {
switch (status) {
case 'start':
return '#52c41a';
case 'end':
return '#52c41a';
case 'process':
return '#1890ff';
default:
return '#faad14';
};
};
// 构建标记点
const markers = computed (() => {
if (!props.routePoints || props.routePoints.length === 0) {
return []
}
return props.routePoints.map((marker, index) => {
// 根据状态设置标记点图标
let iconPath = getMarkerIconByStatus(marker.status);
let customCallout = undefined;
let width = '10px';
let height = '10px';
switch (marker.status) {
case 'start':
customCallout={
anchorY: 0,
anchorX: 0,
display:"ALWAYS",//一直展示
}
width = '28px';
height = '34px';
break;
case 'end':
customCallout ={
anchorY: 0,
anchorX: 0,
display:"ALWAYS",//一直展示
}
width = '28px';
height = '34px';
break;
case 'process':
width = '20px';
height = '15px';
break;
}
const markerId = `marker_${index}`;
// marker.id ||
return {
id: index || markerId,
longitude: marker.longitude,
latitude: marker.latitude,
title: marker.title,
iconPath,
width,
height,
customCallout,
joinCluster: true,
zIndex:1,
...marker
}
})
})
// 构建路线
const polylineId = ref('logistics-route');
const polyline = computed(() => {
if (!props.routePoints || props.routePoints.length < 2) {
return []
}
const points = props.routePoints.map(point => ({
longitude: point.longitude,
latitude: point.latitude
}))
return [{
id: polylineId.value,
points,
color: '#007AFF',
width: 6,
dottedLine: false,
borderWidth: 1,
borderColor: '#0056b3'
}]
})
// 要显示在可视区域内的坐标点列表
const includePoints = computed(()=>{
const points = props.routePoints.map(point => ({
longitude: point.longitude,
latitude: point.latitude
}))
return points;
})
// 闭合多边形
const polygon = computed(()=>{
const points = props.routePoints.map(point => ({
longitude: point.longitude,
latitude: point.latitude
}))
return {
points,
strokeWidth:1,
strokeColor:'red',
fillColor:'lightgreen'
};
})
// 设置地图中心
const mapInstance = computed (() => {
// const mid = props.routePoints[Math.floor(props.routePoints.length / 2)];
const mid = props.routePoints[0];
return {
longitude: mid.longitude,
latitude: mid.latitude
}
})
// 缩放级别
const mapScale = ref(12);
const markerList = ref([])
const drawMap=()=>{
// nextTick(()=>{
// setTimeout(()=>{
// markerList.value = markers.value;
// mapContext.value.includePoints({
// points:includePoints.value,
// padding: [40, 40, 40, 40],
// success:(res)=>{
// console.log('success==>',res);
// },
// fail:(err)=>{
// console.log('fail==>',err);
// },
// complete:(res) => {
// console.log('complete', res)
// }
// })
// },0)
// })
}
defineExpose({
drawMap
})
</script>
<style lang="scss" scoped>
.pMap {
overflow: hidden;
&-box {
width: 100%;
height: 500rpx;
&-callout{
position: relative;
&-list{
position: relative;
&-item{
position: relative;
display: inline-block;
border-radius: 6px;
background: rgba(255, 255, 255, 1);
padding: 8rpx 20rpx;
overflow: hidden;
&-center{
display: flex;
&-tag{
border-radius: 4px;
background: rgba(207, 19, 0, 0.4);
// width: 36rpx;
// height: 36rpx;
// line-height: 36rpx;
padding: 6rpx 10rpx;
// margin: 6rpx 10rpx;
color: rgba(207, 19, 0, 1);
font-size: 20rpx;
font-weight: 500;
overflow: hidden;
}
&-txt{
margin-left: 10rpx;
color: rgba(0, 0, 0, 1);
font-size: 24rpx;
font-weight: 400;
line-height: 28rpx;
}
}
}
}
}
}
}
更多关于uni-app map marker 上的自定义气泡 customCallout显示气泡不对的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于uni-app map marker 上的自定义气泡 customCallout显示气泡不对的实战教程也可以访问 https://www.itying.com/category-93-b0.html
根据你的代码分析,customCallout显示异常可能有以下几个原因:
-
cover-view层级问题:customCallout使用的cover-view在map组件中必须直接作为map的子节点,你的代码中使用了slot="callout"是正确的,但要注意cover-view的样式定位。
-
marker-id绑定问题:确保每个cover-view的marker-id与对应marker的id完全一致。你的代码中marker.id使用了index,而cover-view绑定的也是item.id,这基本正确。
-
anchorX/anchorY设置:你设置的anchorX:0和anchorY:0会将气泡定位在marker的左上角,这可能导致气泡显示位置偏移。建议尝试:
customCallout: { anchorY: -20, // 向上偏移 anchorX: 0, display: "ALWAYS" } -
样式问题:cover-view的样式需要特别注意:
- 避免使用rpx单位,建议使用px
- 确保有明确的宽度设置
- 添加白色背景和边框以增强可见性
-
时机问题:确保markers数据在map渲染完成后再设置。你可以在onMounted中添加延迟:
onMounted(() => { setTimeout(() => { // 重新设置markers数据 }, 100) })

