前端开发
在 React/Vue/Svelte/Angular 等…
当需要在主流前端框架中初始化 Mapbox GL JS 地图、集成 Search JS、并正确处理生命周期与清理时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 React/Vue/Svelte/A特定
解决思路
- 安装 Mapbox GL JS v3.x:`npm install mapbox-gl@^3.0.0`(生产环境推荐 npm;CDN 仅用于原型,需替换 VERSION 为最新 v3.x)。
- 框架版本要求:React 16.8+(需 hooks,脚手架用 React 19.x)、Vue 2.x+(推荐 Vue 3 Composition API)、Svelte 任意版本(脚手架用 Svelte 5.x)、Angular 2+(脚手架用 Angular 19.x)、Next.js 13.x+(App Router)或 Pages Router 12.x+。
- 安装 Search JS:React 用 `npm install @mapbox/search-js-react@^1.0.0`,其他框架用 `npm install @mapbox/search-js-web@^1.0.0`;两者已含 `@mapbox/search-js-core`,仅在自建搜索 UI 时才直接装 core。
- v2.x 迁移到 v3.x 注意:需要 WebGL 2、`optimizeForTerrain` 选项被移除、TypeScript 类型与 tree-shaking 改进,核心初始化模式无破坏性变更。
- Token 管理:生产环境用环境变量(如 `import.meta.env.VITE_MAPBOX_ACCESS_TOKEN`,CRA 用 `process.env.REACT_APP_MAPBOX_TOKEN`);可用全局 `mapboxgl.accessToken = token`,多地图场景优先在 `new mapboxgl.Map({ accessToken: token, ... })` 中按地图传入。
- 每个集成必须遵守五条核心原则:在正确的生命周期钩子中初始化地图;把地图实例存入组件状态而非每次渲染重建;清理时始终调用 `map.remove()` 防止内存泄漏;用环境变量安全处理 token;导入 CSS `import 'mapbox-gl/dist/mapbox-gl.css'`。
- React 主模式:用 `useRef` 保存地图实例和容器 DOM,在 `useEffect` 中以空依赖数组 `[]` 初始化地图,并在返回的清理函数中调用 `mapRef.current.remove()`;绝不在 render 中初始化地图。
- React + Search JS:用 `useState` 保存输入值,`SearchBox` 传入 `accessToken`、`map={mapRef.current}`、`mapboxgl`、`value`、`proximity={center}`、`onChange`、`marker` 等属性。
- SearchBox 关键配置项:`accessToken`(公开 token)、`map`(须先初始化)、`mapboxgl`(库引用)、`proximity`(`[lng, lat]` 地理偏置)、`marker`(是否显示结果标记)、`placeholder`(占位文本)。
- 搜索框定位:用绝对定位覆盖在地图上,容器设 `position: absolute`、`zIndex: 10`、`width: 300`;常见位置为右上(`top:10px, right:10px`)、左上(`top:10px, left:10px`)、左下(`bottom:10px, left:10px`)。
- 避免错误 1:忘记调用 `map.remove()`——每个 Map 实例都会创建 WebGL 上下文、事件监听器和 DOM 节点,不清理会累积导致内存泄漏;必须在 useEffect 中返回 `() => map.remove()`。
- 避免错误 2:在 render 中初始化地图——React 组件频繁重渲染,每次渲染新建地图会导致无限循环和崩溃;应放在 `useEffect` 中。
- 避免错误 3:未正确保存地图实例——用 `useRef` 保存,以便后续添加图层、标记或调用 `remove()`。
- 避免错误 4(Vue 专属):不要把地图实例放进 `data()`——Vue 的响应式 Proxy 会破坏 mapbox-gl 内部对象标识;应在 `mounted()` 中直接赋值 `this.map = new mapboxgl.Map(...)`,并在 `unmounted()` 中调用 `this.map?.remove()`。
- 避免错误 5:静默的样式/瓦片失败——注册 `map.on('error', (e) => { console.error(e.error || e); })` 以暴露失败,必要时在页面上显示错误信息。
- 避免错误 6:deck.gl 通过 jsDelivr `+esm` 引入会报 `does not provide export named 'makeBatchFromTable'`;改用 UMD bundle(如 `https://unpkg.com/deck.gl@9.1.14/dist.min.js`)或 esm.sh,并用 `MapboxOverlay`(Mapbox IControl)而非裸 `Deck` 作为地图控件。
- 避免错误 7:使用 `mapbox-gl-draw` 时要监听 `draw.create` 并从 `draw.getAll()` 更新 UI;半删除的处理器留下悬空 `});` 会导致页面崩溃。
- 避免错误 8:`map.setStyle(...)` 会替换样式树,之前添加的自定义 source/layer/handler 会被清除;必须监听 `map.on('style.load', onStyleReady)` 并在每次切换样式后重新绑定,而不能只在首次 `load` 时添加图层。
- 按框架查阅参考文件:`references/vue.md`、`references/svelte.md`、`references/angular.md`(含 SSR)、`references/vanilla.md`、`references/web-components.md`、`references/nextjs.md`、`references/common-mistakes.md`、`references/token-management.md`。
适用边界 · 注意事项
- 项目不使用 Mapbox(如使用其他地图服务或完全自研渲染)时不适用。
- 仅做静态地图展示、不需要交互式 GL JS 地图时无需此技能。
- 无法提供 Mapbox access token 或未开通 Mapbox 账号时无法使用。