02. 环境搭建
2026年4月25日 12:58
MapLibre 学习指南:文章导航
在线预览地址:env-00jy66xyyn4y-static.normal.cloudstatic.cn/maplibre-ba…
base 代码仓库地址:
- Gitee:gitee.com/JuliusDeng/…
- GitHub:github.com/xwdeng001/m…
如果这个系列对你有帮助,欢迎给仓库点一个 Star,代码仓库可以拉取到完整的学习代码,在docs目录下有规划良好的.md学习文档,希望可以帮助到你(请给个免费的start哦)。你的支持是我持续更新和完善 MapLibre 学习内容的动力,也能帮助更多正在学习 WebGIS / MapLibre 的前端同学找到这份资料。[个人微信: 1576554007 欢迎一起学习交流]
第一阶段:入门基础(第 1-4 节)
| 节次 | 标题 | 核心内容 | 文档路径 |
|---|---|---|---|
| 01 | 认识 MapLibre GL JS | MapLibre 简介与生态、与 Mapbox 的关系、开源许可、应用场景、与其他地图库(Leaflet/OpenLayers/Cesium)对比 | src/docs/stage1/01.认识MapLibre.md |
| 02 | 环境搭建与第一张地图 | Vue3+Vite 项目创建、安装 MapLibre GL JS、创建第一张地图(Map 构造函数参数详解)、地图容器与响应式尺寸 | src/docs/stage1/02.环境搭建与第一张地图.md |
| 03 | 地图基础操作 | 缩放/平移/旋转/倾斜、flyTo/easeTo/jumpTo 动画方法、fitBounds 自适应范围、地图事件监听(click/move/zoom/load) | src/docs/stage1/03.地图基础操作.md |
| 04 | 地图控件 | NavigationControl、ScaleControl、GeolocateControl、FullscreenControl、AttributionControl、自定义控件(IControl 接口) | src/docs/stage1/04.地图控件.md |
02. 环境搭建与第一张地图
环境准备
前置要求
- Node.js ≥ 18(推荐使用 LTS 版本)
- 包管理器:pnpm(推荐)/ npm / yarn
- IDE:VS Code(推荐安装 Vue - Official 扩展)
创建 Vue 3 + TypeScript 项目
# 使用 Vite 创建项目
pnpm create vite maplibre-base --template vue-ts
# 进入项目
cd maplibre-base
# 安装依赖
pnpm install
安装 MapLibre GL JS
pnpm add maplibre-gl
安装后 package.json 中会出现:
{
"dependencies": {
"maplibre-gl": "^5.x.x"
}
}
创建第一张地图
基本步骤
- 创建一个 HTML 容器元素
- 引入 MapLibre GL JS 和 CSS
- 使用
new maplibregl.Map()初始化地图
最小示例
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import maplibregl from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css' // 必须引入 CSS
/** 地图容器 DOM 引用 */
const mapContainer = ref<HTMLElement>()
/** 地图实例 */
let map: maplibregl.Map | null = null
onMounted(() => {
if (!mapContainer.value) return
map = new maplibregl.Map({
container: mapContainer.value, // 容器元素
style: { // 地图样式
version: 8,
sources: {
osm: {
type: 'raster',
tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
tileSize: 256
}
},
layers: [{
id: 'osm-layer',
type: 'raster',
source: 'osm'
}]
},
center: [116.39, 39.91], // 中心点 [经度, 纬度]
zoom: 10 // 缩放级别
})
})
onBeforeUnmount(() => {
if (map) {
map.remove() // 销毁地图,释放资源
map = null
}
})
</script>
<template>
<div ref="mapContainer" style="width: 100%; height: 100vh;"></div>
</template>
⚠️ 重要:必须引入
maplibre-gl/dist/maplibre-gl.css,否则地图控件样式会异常。
Map 构造函数参数详解
new maplibregl.Map(options) 接受一个配置对象,以下是核心参数:
必填参数
| 参数 | 类型 | 说明 |
|---|---|---|
container |
HTMLElement | string |
地图容器,可以是 DOM 元素或元素 ID |
style |
StyleSpecification | string |
地图样式,可以是 JSON 对象或样式 URL |
视图参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
center |
[lng, lat] |
[0, 0] |
地图中心点坐标(经度, 纬度) |
zoom |
number |
0 |
缩放级别(0=全球,18=建筑级别) |
bearing |
number |
0 |
地图旋转角度(0=正北,顺时针) |
pitch |
number |
0 |
地图倾斜角度(0=俯视,60=透视) |
minZoom |
number |
0 |
最小缩放级别 |
maxZoom |
number |
22 |
最大缩放级别 |
maxPitch |
number |
60 |
最大倾斜角度 |
交互参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interactive |
boolean |
true |
是否允许交互 |
scrollZoom |
boolean |
true |
是否允许滚轮缩放 |
boxZoom |
boolean |
true |
是否允许框选缩放 |
dragRotate |
boolean |
true |
是否允许拖拽旋转 |
dragPan |
boolean |
true |
是否允许拖拽平移 |
keyboard |
boolean |
true |
是否允许键盘控制 |
doubleClickZoom |
boolean |
true |
是否允许双击缩放 |
touchZoomRotate |
boolean |
true |
是否允许触摸缩放旋转 |
其他常用参数
| 参数 | 类型 | 说明 |
|---|---|---|
maxBounds |
LngLatBoundsLike |
限制地图可视范围 |
fitBoundsOptions |
object |
fitBounds 的默认配置 |
attributionControl |
boolean |
是否显示归属控件(默认 true) |
hash |
boolean |
是否将地图状态同步到 URL hash |
antialias |
boolean |
是否开启抗锯齿 |
缩放级别含义
| 级别 | 大致比例尺 | 可见内容 |
|---|---|---|
| 0 | 1:500,000,000 | 全球 |
| 3 | 1:70,000,000 | 洲 |
| 5 | 1:18,000,000 | 国家 |
| 8 | 1:2,000,000 | 省 |
| 10 | 1:500,000 | 城市 |
| 13 | 1:70,000 | 城区 |
| 15 | 1:18,000 | 街道 |
| 17 | 1:4,000 | 建筑 |
| 20 | 1:500 | 详细 |
地图样式(Style)
MapLibre 的样式是一个 JSON 对象,遵循 Style Specification。最简结构如下:
{
"version": 8,
"sources": {
"source-name": {
"type": "raster",
"tiles": ["https://tile-server/{z}/{x}/{y}.png"],
"tileSize": 256
}
},
"layers": [
{
"id": "layer-name",
"type": "raster",
"source": "source-name"
}
]
}
使用在线样式 URL
除了手写 JSON,也可以直接传入样式 URL:
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json' // MapLibre 官方演示样式
})
常用免费底图
/** OSM 标准底图 */
const osmStyle = {
version: 8,
sources: {
osm: {
type: 'raster',
tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
tileSize: 256
}
},
layers: [{ id: 'osm', type: 'raster', source: 'osm' }]
}
/** ESRI 卫星影像 */
const satelliteStyle = {
version: 8,
sources: {
satellite: {
type: 'raster',
tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'],
tileSize: 256
}
},
layers: [{ id: 'satellite', type: 'raster', source: 'satellite' }]
}
/** CARTO 暗色底图 */
const darkStyle = {
version: 8,
sources: {
dark: {
type: 'raster',
tiles: ['https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png'],
tileSize: 256
}
},
layers: [{ id: 'dark', type: 'raster', source: 'dark' }]
}
Vue 3 中使用 MapLibre 的注意事项
1. 不要将 Map 实例存为 reactive/ref
// ❌ 错误:会导致 Vue 深度代理 Map 对象,严重影响性能
const map = ref<maplibregl.Map>()
// ✅ 正确:使用普通变量
let map: maplibregl.Map | null = null
MapLibre Map 实例内部有大量 WebGL 上下文和事件监听器,Vue 的响应式代理会干扰其内部状态。
2. 组件卸载时销毁地图
onBeforeUnmount(() => {
if (map) {
map.remove() // 释放 WebGL 上下文和事件监听
map = null
}
})
3. 容器必须有明确的宽高
地图容器 必须 有确定的宽度和高度,否则地图不会渲染:
/* ✅ 正确 */
.map-container {
width: 100%;
height: 100%;
}
/* ❌ 错误 - 高度为 auto 时容器高度为 0 */
.map-container {
width: 100%;
}
4. 地图加载完成后再操作
map.on('load', () => {
// 在这里添加数据源、图层等
map.addSource('my-source', { ... })
map.addLayer({ ... })
})
本课小结
- MapLibre GL JS 通过
npm/pnpm安装,必须同时引入 CSS -
new maplibregl.Map(options)是一切的起点 - 核心参数:
container、style、center、zoom - Vue 中注意:不要用
ref()包裹 Map 实例,卸载时要map.remove() - 容器必须有明确的宽高
📌 上一节:01. 认识 MapLibre 📌 下一节:03. 地图基础操作