uni-app label定位在marker中心位置并出现在上方 Bug反馈
uni-app label定位在marker中心位置并出现在上方 Bug反馈
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | Windows 10 企业版 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:3.1.18
手机系统:Android
手机系统版本号:Android 10
手机厂商:华为
手机机型:华为p20
页面类型:nvue
打包方式:云端
项目创建方式:HBuilderX
App下载地址或H5网址: https://service.dcloud.net.cn/build/download/de6fb160-01a0-11ec-8178-f3baf54d1416
示例代码:
switch(type) {
case 1:
this.covers.push({
id:index+'',
zIndex: index + 900,
latitude: val.lat,
width:40,
height:40,
longitude: val.lng,
iconPath: `/static/img/markers/06-${p.icon}.png`,
label: { //marker气泡
content: `${val.pm10}`,
color: "#333",
bgColor: `${p.color}`,
borderWidth:100,
borderRadius: 10,
fontSize: 12,
textAlign: "center",
padding: padValue,
x: -79,
y: -103,
},
callout: { //marker气泡
content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
color: "#fff",
bgColor: "rgba(15, 158, 250, 1)",
borderRadius: 10,
fontSize: 12,
textAlign: "left",
padding: 6,
display: 'BYCLICK',
}
})
break;
}
操作步骤:
<template>
<view class="" style="height: 100%;">
<map v-if='!mapVis' :scale="scaleValue" :style="{width:'750rpx',height:windowHeight+'px'}" class="map-style" id="myMap" :latitude="latitude" :longitude="longitude" show-location @tap="tapVisPanel" @markertap="markertap"></map>
<map v-if='mapVis' :scale="scaleValue" :style="{width:'750rpx',height:windowHeight+'px'}" class="map-style" id="myMap" :latitude="latitude" :longitude="longitude" :markers="covers" show-location @tap="tapVisPanel" @markertap="markertap"></map>
</view>
</template>
<script>
import api from '@/api/platform.js';
import componentMixin from '@/mixins/componentMixin.js';
import onLoadMixin from '@/mixins/onLoadMixin.js';
export default {
mixins: [onLoadMixin],
components: {},
data() {
return {
mapVis: false,
data: [],
windowHeight: uni.getSystemInfoSync().windowHeight,
title: '站点分布',
IsOption: false,
searchKey: "",
scaleValue: 10,
latitude: '',
longitude: '',
aaa: '',
fixedCovers: [],
covers: [],
pieces: [
{ value: '', color: '#65789B', label: '离线' },
{ value: 0, color: '#3399FF', icon: 'zero', label: '0值' },
{ gt: 0, lte: 50, icon: 'excellent', color: '#61DDAA', label: '优' },
{ gt: 50, lte: 150, icon: 'good', color: '#F6BD16', label: '良' },
{ gt: 150, lte: 250, icon: 'mild', color: '#F6903D', label: '轻度' },
{ gt: 250, lte: 350, icon: 'med', color: '#F46649', label: '中度' },
{ gt: 350, lte: 420, icon: 'serious', color: '#CE1118', label: '重度' },
{ gt: 420, lte: 600, icon: 'severe', color: '#8A0C10', label: '严重' }
],
};
},
onLoad(option) {
this.windowHeight = uni.getSystemInfoSync().windowHeight - 144;
uni.$on('popupPage', (data) => { this.searchHandle(data.content) });
uni.$on('clickTap', (data) => { this.tapOption(data.item) });
uni.$on('handleBadge', (data) => { this.handleMarker(data.index, data.colorValue) });
this.mapCtx = wx.createMapContext('myMap');
this.getAuthorizeInfo();
this.qqmapsdk = new QQMapWX({
key: 'ULWBZ-7D4WV-FNKPY-UOVE6-W4LO5-HCBD3'
});
uni.request({
method: 'get',
url: `https://geoapi.qweather.com/v2/city/lookup?key=4badcc2f942c435e885ace18831fc8e8&location=${option.areaCode}`
}).then(res => {
if (res[1].data.code === '200') {
this.latitude = res[1].data.location[0].lat;
this.longitude = res[1].data.location[0].lon;
}
});
this.getPageData(option.areaCode, option.areaType);
},
methods: {
bindChange(e) {
console.log(e)
},
scaleValueHandle() {
this.scaleValue++
},
tapVisPanel() {
uni.$emit('tapVisPanel', {})
},
markertap(val) {},
// 获取页面数据
getPageData(areaCode, areaType) {
const p1 = new Promise((resolve, reject) => {
api.getStations({ pointType: 0, areaCode: areaCode, areaType: areaType }).then(res => {
resolve({ 'type': 1, 'res': res })
})
})
const p2 = new Promise((resolve, reject) => {
api.getStations({ pointType: 1, areaCode: areaCode, areaType: areaType }).then(res => {
resolve({ 'type': 2, 'res': res })
})
})
const p3 = new Promise((resolve, reject) => {
api.getProjectStations({ areaCode: areaCode, areaType: areaType }).then(res => {
resolve({ 'type': 3, 'res': res })
})
})
Promise.all([p1, p2, p3]).then((result) => {
this.setMap(result)
}).catch((error) => {
console.log(error)
})
},
showSubNuvue() {
let subNvueMap = uni.getSubNVueById('searchAndBar');
subNvueMap.show('slide-in-bottom', 0)
},
setMap(result) {
this.mapVis = false
result.map(item => {
item.res.data.data.forEach((element, index) => {
this.setSign(item.type, element, index)
});
})
this.fixedCovers = this.covers
this.$nextTick(() => {
this.mapVis = true
})
},
setSign(type, val, index) {
this.pieces.map(p => {
if (!val['pm10']) {
val['pm10'] = ''
}
if (val['pm10'] && ((val['pm10'] === p.value) || (p.gt <= val['pm10'] && val['pm10'] < p.lte && val['pm10'] !== ''))) {
let padValue = 6
switch (type) {
case 1:
this.covers.push({
id: index + '',
zIndex: index + 900,
latitude: val.lat,
width: 40,
height: 40,
longitude: val.lng,
iconPath: `/static/img/markers/06-${p.icon}.png`,
label: {
content: `${val.pm10}`,
color: "#333",
bgColor: `${p.color}`,
borderWidth: 100,
borderRadius: 10,
fontSize: 12,
textAlign: "center",
padding: padValue,
x: -79,
y: -103,
},
callout: {
content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
color: "#fff",
bgColor: "rgba(15, 158, 250, 1)",
borderRadius: 10,
fontSize: 12,
textAlign: "left",
padding: 6,
display: 'BYCLICK',
}
})
break;
case 2:
this.covers.push({
id: index + '',
zIndex: index + 900,
latitude: val.lat,
width: 40,
height: 40,
longitude: val.lng,
iconPath: `/static/img/markers/06-${p.icon}.png`,
label: {
content: `${val.pm10}`,
color: "#333",
bgColor: `${p.color}`,
borderWidth: 100,
borderRadius: 10,
fontSize: 12,
textAlign: "center",
padding: padValue,
x: -79,
y: -103,
},
callout: {
content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
color: "#fff",
bgColor: "rgba(15, 158, 250, 1)",
borderRadius: 10,
fontSize: 12,
textAlign: "left",
padding: 6,
display: 'BYCLICK',
}
})
break;
case 3:
this.covers.push({
id: index + '',
zIndex: index + 900,
latitude: val.lat,
width: 40,
height: 40,
longitude: val.lng,
iconPath: `/static/img/markers/07-${p.icon}.png`,
label: {
content: `${val.pm10}`,
color: "#333",
bgColor: `${p.color}`,
borderWidth: 90,
borderRadius: 10,
fontSize: 12,
textAlign: "left",
padding: 7,
x: -74,
y: -96,
},
callout: {
content: `名称:${val.name}\n统计时间:${val.date}\npm10:${val.pm10}`,
color: "#fff",
bgColor: "rgba(15, 158, 250, 1)",
borderRadius: 10,
fontSize: 12,
textAlign: "center",
padding: 5,
display: 'BYCLICK',
}
})
break;
}
}
})
},
//处理covers
handleMarker(val, colorValue) {
this.mapVis = false
this.covers = this.fixedCovers.filter((item) => {
if (item.iconPath.indexOf('03') > -1 && colorValue['1']) {
return item
} else if (item.iconPath.indexOf('04') > -1 && colorValue['2']) {
return item
} else if (item.iconPath.indexOf('05') > -1 && colorValue['3']) {
return item
}
});
this.$nextTick(() => {
this.mapVis = true
})
},
// 搜索框
searchHandle(val) {
let self = this
self.searchKey = val
self.getProjectNameList({ projectName: self.searchKey })
},
getProjectNameList(val) {
api.getProjectNameList(val).then(res => {
this.aaa = res.data.data
uni.$emit('popup-page2', {
data: res.data.data,
})
})
},
tapOption(item) {
let self = this
self.searchKey = item.title
self.IsOption = false
self.data = []
var obj = {}
obj.latitude = item.lat;
obj.longitude = item.lng;
self.scaleValue = 18
self.toLocation(obj)
},
toLocation(obj) {
this.mapVis = false
this.mapCtx.moveToLocation(obj)
this.mapCtx.translateMarker({
markerId: 1,
autoRotate: true,
duration: 100,
destination: {
latitude: obj.latitude,
longitude: obj.longitude,
},
animationEnd() {
if (self.scaleValue == 18) {
self.scaleValue = 17.9
} else {
self.scaleValue = 18
}
}
})
this.$nextTick(() => {
if (self.scaleValue == 18) {
self.scaleValue = 17.9
} else {
self.scaleValue = 18
}
self.latitude = obj.latitude,
self.longitude = obj.longitude,
this.mapVis = true
})
},
mapSearch(keyword, location) {
console.log(keyword, location, "keyword,location")
let promise = new Promise(function(resolve, reject) {
qqmapsdk.search({
keyword: keyword, //搜索关键词
location: location, //设置周边搜索中心点
success: function(res) {
console.log(res)
resolve(res)
},
fail: function(res) {
console.log(12313)
console.log(res)
reject(res)
}
});
})
return promise
},
// 位置授权
getAuthorizeInfo() {
// uni.authorize({
// scope: 'scope.userLocation',
// success() { // 允许授权
// self.getLocationInfo();
// },
// fail() { // 拒绝授权
// self.openConfirm();
// console.log("你拒绝了授权,无法获得周边信息")
// }
// })
},
// 获取地理位置
getLocationInfo() {
uni.getLocation({
type: 'wgs84',
success(res) {
console.log(res, "当前位置");
self.toLocation(res)
self.latitude = res.latitude;
self.longitude = res.longitude;
}
});
},
// 再次获取授权
// 当用户第一次拒绝后再次请求授权
openConfirm() {
uni.showModal({
title: '请求授权当前位置',
content: '需要获取您的地理位置,请确认授权',
success(res) {
if (res.confirm) {
uni.openSetting(); // 打开地图权限设置
} else if (res.cancel) {
uni.showToast({
title: '你拒绝了授权,无法获得周边信息',
icon: 'none',
duration: 1000
})
}
}
});
},
poitap(e) {
console.log(e, "poitap")
var obj = e.detail
self.searchKey = obj.name
self.toLocation(obj)
},
getCenterLocation() {
this.mapCtx.getCenterLocation({
success(res) {
console.log(res.longitude)
console.log(res.latitude)
}
})
}
}
}
</script>
<style lang="less" scoped>
.top-search {
position: absolute;
top: 100px;
right: 10rpx;
z-index: 99999;
background-color: red;
}
map {
position: relative;
}
.btn-wrap {
position: absolute;
top: 180rpx;
left: 100rpx;
z-index: 99999;
background-color: red;
}
.map-style {
// height: calc(100vh - 44px);
// height: 100%;
}
.controls-title {
position: relative;
margin-top: 350rpx;
width: 100%;
text-align: center;
color: red;
}
.bar-wrap {
width: 50rpx;
height: 50rpx;
background-color: red;
}
</style>
预期结果:
同操作步骤中的代码
实际结果:
同操作步骤中的代码
bug描述:
nvue页面使用label得x,y定位后不能适配所有手机 x,y不是用得upx定位

更多关于uni-app label定位在marker中心位置并出现在上方 Bug反馈的实战教程也可以访问 https://www.itying.com/category-93-b0.html
设置label的宽高 然后在设置xy 举例:label: {
content: 11,
fontSize: 20,
width: 60,
height: 60,
bgColor: ‘#00ff00’,
borderRadius: 30,
textAlign: ‘center’,
x: 0,
y: -30,
}
更多关于uni-app label定位在marker中心位置并出现在上方 Bug反馈的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你就是秀儿
demo 直接运行进去首页
demo运行不起来 弄个简单demo重新提交一下
有没有哪位大佬再看 我们这边客户一直在催
手机这里我用得是p20调试得 这个调试好了 但是其他手机不适配
x y本身就是逻辑像素了 理论上不会相差很大。不同手机偏差很大?
很大 我是按p20调试出来的x,y 比p20小得手机在右下方 还挺多得,比p20屏幕大得手机 左上方 距离挺远得 逻辑上来说 不设置应该喝 经纬度在一起呢
回复 囿于江湖: 设置label的宽高 然后在设置xy 举例:label: { content: markerIds.length + ‘’, fontSize: 20, width: 60, height: 60, bgColor: ‘#00ff00’, borderRadius: 30, textAlign: ‘center’, x: 0, y: -30, }
你需要连接到手机上 我这个进去第一个页面就是nvue
根据你提供的代码和问题描述,这是一个典型的marker label定位适配问题。问题核心在于label的x和y坐标在不同设备上表现不一致。
在uni-app的map组件中,label的x和y坐标单位是像素(px),而不是rpx或upx。你的代码中设置了x: -79, y: -103,这些是固定像素值,在不同分辨率的设备上会出现定位偏差。
解决方案是动态计算x和y的值:
- 获取设备像素比:
const systemInfo = uni.getSystemInfoSync();
const pixelRatio = systemInfo.pixelRatio;
- 根据marker图标尺寸计算偏移量:
// 假设你的marker图标是40x40
const markerWidth = 40;
const markerHeight = 40;
// 计算label居中所需的偏移量
const x = -markerWidth / 2;
const y = -markerHeight - 10; // 10是label与marker的间距
- 应用到label配置:
label: {
content: `${val.pm10}`,
color: "#333",
bgColor: `${p.color}`,
borderWidth: 100,
borderRadius: 10,
fontSize: 12,
textAlign: "center",
padding: padValue,
x: x,
y: y,
}

