BAT交易所官网客户端V1.13.0 安卓版
220.3MB · 2025-09-18
我先打开并浏览 src/views/wlhy/baidumap/bf9-16-2.vue
,梳理其与 Map.vue
的差异点和事件绑定、销毁、输入处理等实现,以便做对照复盘。
[1 tool called]
我先通读了 src/views/wlhy/baidumap/bf9-16-2.vue
,对照今天在 Map.vue
的修复点,做一次聚焦性的复盘与改进建议。
AMap
的抽屉式地图选点;带搜索框、搜索按钮、结果面板 panel
、地图标记与定位等能力。Map.vue
不同的实现策略。:id="mapContainerId"
与 :id="tipInputId"
的动态容器与输入框 ID,理论上可以避免 DOM 复用导致的实例绑定陈旧问题。@afterVisibleChange
驱动初始化,配合 MutationObserver、反复 resize()
、甚至“移除并重建地图容器”的兜底路径,增强了在复杂布局/动画场景下的渲染稳定性。panel
”交互,用户心智简单,便于定位问题。initAMapPlugins()
内完成 AutoComplete
、PlaceSearch
、ToolBar
初始化与事件绑定。AutoComplete 未使用动态 ID,实际绑定仍然是硬编码 'tipinput'
<input ... :id="tipInputId" ...>
document.getElementById('tipinput')
、input: 'tipinput'
tipInputId
变化时,AutoComplete
可能绑定到不存在或旧的节点,导致选择事件丢失。document.getElementById(this.tipInputId)
和 input: this.tipInputId
。方法重复定义,存在覆盖与维护风险
getCurrentPosition
定义了两次(L193 与 L1090 附近),后者会覆盖前者。handleKeywordInput
定义了两次(L242 与 L765 附近),后者会覆盖前者。资源释放方式与兼容性
this.autoComplete.destroy()
、this.placeSearch.destroy()
(L408、L409、L889、L890、L1295、L1303),在某些版本/构造器上可能没有 destroy()
,导致报错(这正是 Map.vue
中出现过的警告来源之一)。typeof ...destroy === 'function'
守卫,或使用事件解绑 + 置空的方式收尾。事件模型混用
PlaceSearch
使用了 .on('complete')
/.on('error')
(L705、L706),也使用了 search(kw, callback)
的回调风格(L249)。API 版本不同事件模型不同,容易引发“双通道回调”或空回调。过度复杂的渲染兜底路径
MutationObserver
、多次 resize()
、定时器兜底、甚至“删除并重建地图容器”(L443-L451、L589-L663、L878-L926)。虽然鲁棒,但复杂度较高,后续维护成本与副作用(例如插件状态丢失)上升。细节一致性
visible
监听中会条件初始化地图或强制重绘(L169-L176),同时 afterDrawerVisibleChange
也负责初始化(L455-L545),实际存在两处入口的竞态可能。afterVisibleChange
统一入口。Map.vue
的修复重心:
AutoComplete.on('select', ...)
+ PlaceSearch
Fallback;destroy()
;keyword
(而你明确说明此文件无需同步这一点)。bf9-16-2.vue
更偏“工程兜底型”:
initAMapPlugins()
中
document.getElementById('tipinput')
→ document.getElementById(this.tipInputId)
input: 'tipinput'
→ input: this.tipInputId
getCurrentPosition
与 handleKeywordInput
,只保留一份。destroy()
:
destroy()
改为先判断类型,或仅做 事件解绑 + 置空
。PlaceSearch
只保留一种回调方式(建议保留 .on('complete')/.on('error')
或 search(kw, cb)
二选一)。AutoComplete
与 PlaceSearch
,按钮搜索可见 panel
。afterDrawerVisibleChange
+ 观察器重试能恢复地图;若不改动 ID 硬编码,select
有概率因节点不匹配而不触发。destroy()
的情况下,可能产生控制台警告。如果你愿意,我可以按“最小修正”帮你把上述四点直接在 bf9-16-2.vue
中落地,保持交互不变,仅提升稳定性与一致性。
AutoComplete
的 select
事件;关闭后再次打开,输入关键词搜索,select
事件不再触发。keyword
。id="tipinput"
在抽屉反复打开/关闭后,旧 DOM 被销毁但 AutoComplete
仍引用旧节点。on/choose/complete/addListener
等并行方案,进一步引发重复绑定、误判、竞态。data
: 新增 tipInputId: 'tipinput-' + Date.now()
。template
: 关键词输入框改为 :id="tipInputId"
。show()
: 每次打开生成新 ID:this.tipInputId = 'tipinput-' + Date.now();
initMap()
:
mapGD
。AMap.plugin
内部初始化 AutoComplete
与 PlaceSearch
。AutoComplete
仅保留核心:this.autoComplete.on('select', this.onAutocompleteSelect)
。complete
后标记 mapInitialized=true
并执行 checkAndLocate()
。close()
:
AutoComplete
的 select
事件(off('select', ...)
),将实例置空。currentMarker
,销毁 mapGD
,重置状态变量。keyword/location/inputLng/inputLat
)。onAutocompleteSelect(e)
: 优先直接用 e.poi.location
定位、打点、更新 addrInfo
,无 location 时再走 placeSearch
。handlePOISelection(poi)
: 封装“根据 POI 更新地图与地址信息”,兼容多种 location
结构。handleManualSelection(selectedText)
以便在极端情况下根据文本触发 placeSearch
。show()
首行清空关键词:this.keyword = ''
,满足“每次进入清空”的需求。visible
变化时触发 map.resize()
,避免首次渲染尺寸为 0 导致白屏。select
正常触发。tipInputId
更新,AutoComplete
绑定到全新 DOM,select
可持续触发。keyword
,会在后续逻辑中覆盖为传入值(兼容业务场景)。destroy()
:所有销毁调用前均做了类型检查或改为安全置空。close()
中集中清理,且默认不再附加额外 DOM 监听,避免重复与干扰。complete
事件做选择:统一以 select
为主,placeSearch
为 fallback。autoComplete.setCity()
与 placeSearch.setCity()
。placeSearch.search(keyword)
,避免全局 DOM 监听。show()
中生效,不影响传参覆盖。Map.vue
处于可复现、可维护、行为稳定的状态。我先复盘,再给出可执行的修复要点与自检清单。
id
/DOM 还没渲染就初始化),引发搜索正常但地图未刷新中心或未重绘。visible
改变时调用 resize
,时机过早,抽屉动画未结束,仍为 0 尺寸。@afterVisibleChange
和 MutationObserver
监听容器尺寸,尺寸有效时再 initMap()
,否则等待。div#mapContainerId
并挂回父节点,再初始化地图。mapGD.resize()
,并在插件加载后再次 resize()
。AutoComplete
与 PlaceSearch
每次初始化都销毁旧实例,绑定到当前 mapGD
,并保证输入框、面板 DOM 存在后再初始化。.map-gaode-container
配置固定高度(如 500px),抽屉内布局不要依赖内容自适应高度。afterVisibleChange(true)
→ 容器尺寸检测通过 → new AMap.Map(...)
→ 插件加载 → resize()
→ 定位/打点。mapGD
和插件、移除容器或清空容器;打开时按上面流程重建。#mapContainerId
的 offsetWidth/offsetHeight
是否 > 0?container.querySelector('canvas')
是否存在,canvas 宽高是否为 0?mapGD.getSize()
是否非 0?mapGD.resize()
是否被调用过(并在抽屉动画后调用)?mapGD
,输入框/面板 DOM 是否已渲染后再初始化?destroy()
,二次打开是否复用旧 DOM/实例?如果你更倾向“不用动态样式”,我可以把目前 watch 里设置容器内联样式的逻辑改成纯 CSS 类方式,并保留上述延后初始化与 resize
策略。你要我直接改成纯 CSS 版本吗?
220.3MB · 2025-09-18
93.2MB · 2025-09-18
281.41MB · 2025-09-18