Vue.js结合v-ymap切换城市后地图不更新、properties报错如何解决
问题排查与修复方案
报错原因
属性校验失败报错有两个核心触发点:
- 地图中心坐标赋值时使用
toFixed()返回的字符串类型,不符合v-ymap要求的数字数组格式 - 直接同步清空markers数组时,点位组件批量销毁的逻辑触发了v-ymap内部对
properties属性的空值校验规则
修复步骤
1. 修复坐标类型错误
将placeMarks方法中坐标赋值的代码修改为数字类型:
// 旧代码 // $this.settings.coords = [midLat.toFixed(6), midLng.toFixed(6)]; // 新代码 $this.settings.coords = [Number(midLat.toFixed(6)), Number(midLng.toFixed(6))];
2. 优化markers数组更新逻辑
不要先清空数组再逐个push,改为先构建完整的新标记数组,再一次性替换,避免中间出现空数组状态触发校验问题:
placeMarks(marks) { const newMarkers = [] let lat = 0 let lng = 0 this.noPoints = null marks.forEach(obj => { // 原有构建气球内容的逻辑保持不变 let newString = '<div class="map-info map-info_on-map"><div class="map-info__in">'; newString += '<div class="map-info__header">' + '<p>' + obj.Name + '</p>' + '</div>' + '<div class="text text_black map-info__address">' + '<p>' + obj.Address + '</p>' + '</div>'; if (obj.WorkTime) { newString += '<div class="text text_black map-info__time">' + '<p>' + obj.WorkTime + '</p>' + '</div>'; } if (obj.Phone) { newString += '<div class="text text_black map-info__phone">' + '<a href="tel:' + obj.Phone + '">' + obj.Phone + '</a>' + '</div>'; } newString += '</div></div>' lat += parseFloat(obj.cY) lng += parseFloat(obj.cX) newMarkers.push({ id: obj.id, coords: [obj.cY, obj.cX], clusterCaption: obj.Name, balloonContentheader: '', balloonContentBody: newString, balloonContentFooter: '', hintContent: '', PVZaddr: obj.FullAddress, PVZ_city: obj.City }) }) // 先更新地图中心坐标 const midLat = lat / newMarkers.length const midLng = lng / newMarkers.length this.settings.coords = [Number(midLat.toFixed(6)), Number(midLng.toFixed(6))] // 最后一次性替换标记数组 this.markers = newMarkers }
3. 优化模板结构
将v-if和v-for拆分到不同节点,避免同节点使用两个指令导致的渲染异常,同时补全v-for的key属性,删除v-ymap上重复绑定的coords属性:
// 下拉框部分,删除多余的selected属性,补全key select(v-model="curCity") option( v-for="city in Doption" :key="city.value" :value ="city.value" :name = "city.label" :disabled ="dsbl == 1" ) {{ city.label }} // 地图渲染部分 v-ymap( v-if="settings.coords" :center="settings.coords" :zoom="settings.zoom" :YMAPS_KEY="settings.apiKey" :behaviors=["drag", "dblClickZoom", "rightMouseButtonMagnifier", "multiTouch"] ) template(v-if="markers.length") v-ymap-placemark( v-for="marker in markers" :key="marker.id" :geometry="marker.coords" :properties="{balloonContentBody: marker.balloonContentBody}" :options="{iconLayout:'default#image', iconImageHref: '/images/icons/map-pin.svg', iconImageSize: [40, 52], iconImageOffset: [-15, -38]}" )
内容的提问来源于stack exchange,提问作者Necro The Human
相关产品推荐
相关产品推荐

