Overview
This guide covers embedding Baidu Maps in a Vue.js application with features including route planning, trajectory tracking, markers, and map type switching.
Prerequisites
Install the vue-baidu-map package:
npm install vue-baidu-map --save
Configuration
Obtain a API key (AK) from the Baidu Maps API platform. Register your application and note the generated AK.
Project Setup
Register the plugin in main.js:
import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap, {
ak: 'YOUR_BAIDU_MAP_API_KEY'
})
Map Component Implemantation
Create a map component with trajectory and routing capabilities:
<template>
<div class="map-container">
<el-card style="height: 60vh">
<baidu-map
class="bm-view"
:zoom="15"
:center="mapCenter"
inertial-dragging
@ready="onMapReady"
:scroll-wheel-zoom="true"
>
<!-- Geolocation Control -->
<bm-geolocation
anchor="BMAP_ANCHOR_BOTTOM_RIGHT"
:showAddressBar="true"
:autoLocation="true"
/>
<!-- Map Type Switcher -->
<bm-map-type
:map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']"
anchor="BMAP_ANCHOR_TOP_LEFT"
/>
<!-- Navigation Controls -->
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT" />
<!-- Trajectory Polyline -->
<new-polyline
:path="trajectoryPath"
:editing="false"
:icons="directionIcons"
stroke-color="#8ba0fb"
:stroke-opacity="1"
:stroke-weight="8"
/>
<!-- Start Marker -->
<bm-marker :position="originPoint" :dragging="true">
<bm-label
content="Start"
:labelStyle="{ color: 'black', fontSize: '16px' }"
:offset="{ width: -35, height: 30 }"
/>
</bm-marker>
<!-- End Marker -->
<bm-marker :position="destinationPoint" :dragging="true">
<bm-label
content="End"
:labelStyle="{ color: 'black', fontSize: '16px' }"
:offset="{ width: -35, height: 30 }"
/>
</bm-marker>
</baidu-map>
</el-card>
</div>
</template>
<script>
import {
BaiduMap,
BmControl,
BmView,
BmAutoComplete,
BmLocalSearch,
BmMarker,
BmGeolocation,
BmlLushu
} from "vue-baidu-map";
import newPolyline from "./new_polyline.vue";
export default {
components: {
BaiduMap,
BmControl,
BmView,
BmAutoComplete,
BmLocalSearch,
BmMarker,
BmGeolocation,
newPolyline,
BmlLushu,
},
data() {
return {
mapCenter: {
lng: 116.404,
lat: 39.915
},
trajectoryPath: [
{ lng: 116.404, lat: 39.915 },
{ lng: 116.405, lat: 39.920 },
{ lng: 116.423493, lat: 39.907445 }
],
vehiclePath: [],
originPoint: { lng: 116.404, lat: 39.915 },
destinationPoint: { lng: 116.423493, lat: 39.907445 },
directionIcons: [],
icon: {
url: "https://s1.ax1x.com/2023/06/20/pC80IAJ.png",
size: {
width: 52,
height: 52,
},
labelText: "Vehicle",
color: "",
start: "",
end: "",
speed: 20,
showPath: false,
enableRotation: true,
BMaps: undefined
},
};
},
methods: {
fetchRouteData() {
fetchRouteDetails(this.routeId).then(response => {
if (response.status === 200) {
this.routeData = response.data;
const waypoints = JSON.parse(response.data.path).map(point => ({
lng: point.longitude,
lat: point.latitude,
}));
this.trajectoryPath = waypoints;
this.updateTrajectory();
}
});
},
onMapReady({ BMap, map }) {
this.fetchRouteData();
this.vehiclePath = [];
const app = this;
// Convert trajectory points to BMap coordinates
this.trajectoryPath.forEach(point => {
this.vehiclePath.push(
new BMap.Point(point.lng, point.lat)
);
});
// Configure direction arrow symbols
const arrowSymbol = new BMap.Symbol(BMap_Symbol_SHAPE_FORWARD_OPEN_ARROW, {
scale: 1,
strokeColor: "#fff",
strokeWeight: "2"
});
const arrowIcon = new BMap.IconSequence(arrowSymbol, "10", "30");
app.directionIcons.push(arrowIcon);
},
resetPlayback() {
this.isPlaying = false;
},
updateTrajectory() {
this.startPoint = this.trajectoryPath[0];
this.endPoint = this.trajectoryPath[this.trajectoryPath.length - 1];
this.isPlaying = true;
},
},
created() {
if (this.routeId) {
this.fetchRouteData();
}
},
};
</script>
<style>
.bm-view {
height: 500px;
margin-top: 20px;
width: 100%;
}
.map-container {
float: left;
width: 100%;
}
</style>
Custom Polyline Component
To render polylines with directional arrows, create a custom component:
<template>
<div></div>
</template>
<script>
import commonMixin from "vue-baidu-map/components/base/mixins/common.js";
import bindEvents from "vue-baidu-map/components/base/bindEvent.js";
import { createPoint } from "vue-baidu-map/components/base/factory.js";
export default {
name: "new-polyline",
render() {},
mixins: [commonMixin("overlay")],
props: {
path: {
type: Array
},
icons: {
type: Array
},
strokeColor: {
type: String
},
strokeWeight: {
type: Number
},
strokeOpacity: {
type: Number
},
strokeStyle: {
type: String
},
massClear: {
type: Boolean,
default: true
},
clicking: {
type: Boolean,
default: true
},
editing: {
type: Boolean,
default: false
}
},
watch: {
path: {
handler(val, oldVal) {
this.reload();
},
deep: true
},
strokeColor(val) {
this.originInstance.setStrokeColor(val);
},
strokeOpacity(val) {
this.originInstance.setStrokeOpacity(val);
},
strokeWeight(val) {
this.originInstance.setStrokeWeight(val);
},
strokeStyle(val) {
this.originInstance.setStrokeStyle(val);
},
editing(val) {
val
? this.originInstance.enableEditing()
: this.originInstance.disableEditing();
},
massClear(val) {
val
? this.originInstance.enableMassClear()
: this.originInstance.disableMassClear();
},
clicking(val) {
this.reload();
}
},
methods: {
load() {
const {
BMap,
map,
path,
icons,
strokeColor,
strokeWeight,
strokeOpacity,
strokeStyle,
editing,
massClear,
clicking
} = this;
const overlay = new BMap.Polyline(
path.map(item =>
createPoint(BMap, {
lng: parseFloat(item.lng),
lat: parseFloat(item.lat)
})
),
{
strokeColor,
strokeWeight,
strokeOpacity,
strokeStyle,
icons,
enableEditing: editing,
enableMassClear: massClear,
enableClicking: clicking
}
);
this.originInstance = overlay;
map.addOverlay(overlay);
bindEvents.call(this, overlay);
}
}
};
</script>
Key Components
| Component | Purpose |
|---|---|
| BaiduMap | Main map container |
| BmGeolocation | User location detection |
| BmMapType | Switch between map types |
| BmNavigation | Zoom controls |
| BmMarker | Location markers |
| BmlLushu | Enimated marker movement |
| Custom Polyline | Trajectory visualization |
Available Map Types
BMAP_NORMAL_MAP- Standard map viewBMAP_HYBRID_MAP- Satellite view with labels