forked from zhouruizhe/gmTouringMiniApp
fix(map): 收敛 regionchange 回写回路,修复选中标点后地图抽动
AI Code Review / review (pull_request) Successful in 2m11s
AI Code Review / review (pull_request) Successful in 2m11s
选中标点后地图在左右/上下反复抽动,根因是视口回写形成了自激回路: map 的 longitude/latitude/scale 绑定到 store,而 regionchange 又无条件把 地图当前中心点写回 store —— 写 store 触发地图移动,移动结束回传一个 「差一点点」的中心点,再写回,再移动。上一个提交把中心点改成从 detail.centerLocation 同步读取后,回路里原本靠 getCenterLocation 异步跳变 掩盖住的这一点噪声就直接闭合了。 两道闸: - 只接受手势造成的变化。causedBy 为 update(我们自己改绑定值或调 includePoints 触发)时 store 已是权威值,不回写。老基础库拿不到 causedBy 时退化到下一道闸。 - 所有回写走 commitViewport,经 isSignificantViewportChange 过滤掉小于 1e-4 度 / 0.01 级的变化。远小于任何一次真实拖动,足以吸收量化噪声。 顺带修一个 H5 构建回归(1bcdd40 引入):uni 的 H5 路由生成器按路径推导 组件标识,pages/poi/detail 与 pages-poi/detail 都归一成 PagesPoiDetail, 重复声明导致 build:h5 失败。兼容跳板必须留在旧路径上,所以改名分包路由 pages-poi/detail -> pages-poi/poi-detail。
This commit is contained in:
@@ -66,7 +66,7 @@ function openItinerary() {
|
||||
}
|
||||
|
||||
function openDetail(poiId: string) {
|
||||
uni.navigateTo({ url: `/pages-poi/detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
uni.navigateTo({ url: `/pages-poi/poi-detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
}
|
||||
|
||||
function focusOnMap(poiId: string) {
|
||||
|
||||
@@ -53,7 +53,7 @@ function openPoi(poiId: string) {
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url: `/pages-poi/detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
uni.navigateTo({ url: `/pages-poi/poi-detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
}
|
||||
|
||||
function loadProfile() {
|
||||
|
||||
@@ -284,7 +284,7 @@ function openPlanner() {
|
||||
}
|
||||
|
||||
function openDetail(poiId: string) {
|
||||
uni.navigateTo({ url: `/pages-poi/detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
uni.navigateTo({ url: `/pages-poi/poi-detail?poiId=${encodeURIComponent(poiId)}` })
|
||||
}
|
||||
|
||||
function focusOnMap(poiId: string) {
|
||||
|
||||
+32
-10
@@ -7,7 +7,7 @@ import PoiSummaryCard from '@/components/map/PoiSummaryCard.vue'
|
||||
import PageState from '@/components/poi/PageState.vue'
|
||||
import { getPoiRepository } from '@/data/poi'
|
||||
import { isTrustworthyCoordinate } from '@/domain/poi'
|
||||
import { buildMarkerIdMap, createPoiMarkers } from '@/services/map'
|
||||
import { buildMarkerIdMap, createPoiMarkers, isSignificantViewportChange } from '@/services/map'
|
||||
import { getSessionPlanningOrigin, loadPlan } from '@/services/travel-assistant'
|
||||
import { useLocationStore, useMapStore } from '@/stores'
|
||||
|
||||
@@ -292,7 +292,11 @@ function readEventCenter(detail: Record<string, unknown>): GeoPoint | null {
|
||||
return null
|
||||
}
|
||||
|
||||
function updateViewport(event: { type: string, detail: Record<string, unknown> }) {
|
||||
function updateViewport(event: {
|
||||
type: string
|
||||
causedBy?: unknown
|
||||
detail: Record<string, unknown>
|
||||
}) {
|
||||
const changeType = String(event.detail.type ?? event.type ?? '')
|
||||
if (changeType !== 'end')
|
||||
return
|
||||
@@ -300,6 +304,15 @@ function updateViewport(event: { type: string, detail: Record<string, unknown> }
|
||||
if (!mapReady.value || navigating.value)
|
||||
return
|
||||
|
||||
// 只接受用户手势造成的视野变化。
|
||||
//
|
||||
// `causedBy: 'update'` 是我们自己改 longitude/latitude/scale 或调 includePoints
|
||||
// 触发的回调 —— 此时 store 已经是权威值,再把地图回传的落点写回去会形成
|
||||
// 「写 store → 地图动 → regionchange → 写 store」的自激回路,表现为地图反复抽动。
|
||||
const causedBy = String(event.causedBy ?? event.detail.causedBy ?? '')
|
||||
if (causedBy && causedBy !== 'drag' && causedBy !== 'scale' && causedBy !== 'gesture')
|
||||
return
|
||||
|
||||
const eventScale = Number(event.detail.scale)
|
||||
const fallbackScale = Number.isFinite(eventScale) ? eventScale : viewport.value.scale
|
||||
|
||||
@@ -319,6 +332,19 @@ function updateViewport(event: { type: string, detail: Record<string, unknown> }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* regionchange 回写 store 的唯一入口。
|
||||
*
|
||||
* 只有超过阈值的变化才写:地图的中心点是绑定到 store 的,写回去会再次触发地图移动,
|
||||
* 把量化噪声原样回灌就会自激。见 isSignificantViewportChange 的注释。
|
||||
*/
|
||||
function commitViewport(longitude: number, latitude: number, scale: number) {
|
||||
const next = { longitude, latitude, scale }
|
||||
if (!isSignificantViewportChange(viewport.value, next))
|
||||
return
|
||||
mapStore.updateViewport(next)
|
||||
}
|
||||
|
||||
function updateViewportWithScale(longitude: number, latitude: number, fallbackScale: number) {
|
||||
const context = mapContext.value as (ReturnType<typeof uni.createMapContext> & {
|
||||
getScale?: (options: {
|
||||
@@ -328,21 +354,17 @@ function updateViewportWithScale(longitude: number, latitude: number, fallbackSc
|
||||
}) | null
|
||||
|
||||
if (!context?.getScale) {
|
||||
mapStore.updateViewport({ longitude, latitude, scale: fallbackScale })
|
||||
commitViewport(longitude, latitude, fallbackScale)
|
||||
return
|
||||
}
|
||||
|
||||
context.getScale({
|
||||
success: (result) => {
|
||||
const scale = Number(result.scale)
|
||||
mapStore.updateViewport({
|
||||
longitude,
|
||||
latitude,
|
||||
scale: Number.isFinite(scale) ? scale : fallbackScale,
|
||||
})
|
||||
commitViewport(longitude, latitude, Number.isFinite(scale) ? scale : fallbackScale)
|
||||
},
|
||||
fail: () => {
|
||||
mapStore.updateViewport({ longitude, latitude, scale: fallbackScale })
|
||||
commitViewport(longitude, latitude, fallbackScale)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -506,7 +528,7 @@ function openDetail(poiId: string) {
|
||||
return
|
||||
navigating.value = true
|
||||
uni.navigateTo({
|
||||
url: `/pages-poi/detail?poiId=${encodeURIComponent(poiId)}`,
|
||||
url: `/pages-poi/poi-detail?poiId=${encodeURIComponent(poiId)}`,
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
navigating.value = false
|
||||
|
||||
@@ -26,7 +26,7 @@ onLoad((query) => {
|
||||
|
||||
// redirectTo 而非 navigateTo:跳板本身不该留在页面栈里。
|
||||
uni.redirectTo({
|
||||
url: `/pages-poi/detail?poiId=${encodeURIComponent(rawPoiId)}`,
|
||||
url: `/pages-poi/poi-detail?poiId=${encodeURIComponent(rawPoiId)}`,
|
||||
fail: () => {
|
||||
uni.showToast({ title: REDIRECT_FAILURE_TOAST, icon: 'none' })
|
||||
fallbackToMap()
|
||||
|
||||
Reference in New Issue
Block a user