这是我的千日蜕变计划第二篇,我计划在未来的1000天,三天更新一篇博客。希望大家监督,也希望自己可以坚持。
内容:uni-app实现基础的导航功能 来源: 工作日常
功能分析
- 获取用户当前的位置
- 获取当前位置到目的地的路线规划
- 切换步行、骑行、驾车三种切换
- 调用第三方导航
效果图如下:

代码部分
html部分
<view>
<view class="map-wrapper">
<map :latitude="latitude" scale="12" :longitude="longitude" :markers="markers" :polyline="polyline" ></map>
<view class="info-wrapper">
<view class="selectType">
<view @click="goTo('car')" class="type" :class="active === 'car' ? 'active' : ''">驾车</view>
<view @click="goTo('walk')" class="type" :class="active === 'walk' ? 'active' : ''">步行</view>
<view @click="goTo('ride')" class="type" :class="active === 'ride' ? 'active' : ''">骑行</view>
</view>
<view class="navigatePic" @click="handleNavigate">导航</view>
<view v-if="maxDuration && active!=='car'" class="info">
<text>距离太远,请选择合适的方式前往</text>
</view>
<view v-else class="info">
<text>{{duration | formatTime}}小时</text>
<text>{{distance | filterDistance}}公里</text>
</view>
</view>
</view>
</view>
</view>
JS部分
- 数据部分
// 第一步: 需要引用高德导航的js文件
import amapFile from './amap-wx.js';
data() {
return {
title: 'map',
latitude: xxx, // 目的地的位置
longitude: xxx, // 目的地的位置
key: 'c290b7e016c85e8f279b2f80018c6fbf', // 高德导航的key
distance: 0,
duration: 0,
maxDuration: false,
curentLatitude: '',
curentLongitude: '',
active: 'car',
polyline: null,
markers: [{
latitude: 28.193688,
longitude: 113.010925,
// iconPath: '地图的标注icon',
title:'xxx',
label:{
content:'xxx',
color:'#F76350',
bgColor:'#fff',
padding:5,
borderRadius:4
},
callout:{
content:'xxx',
color:'#F76350',
fontSize:12
}
}, {
latitude: 28.188597,
longitude: 113.006853,
// iconPath: '地图的标注icon',
title:'您的位置',
label:{
content:'您的位置',
color:'#F76350',
bgColor:'#fff',
padding:5,
borderRadius:4
},
callout:{
content:'您的位置',
color:'#F76350',
fontSize:12
}
}]
}
},
- 页面加载的时候执行的方法
// 获取当前用户的位置
uni.getLocation({
type: 'gcj02',
success: (res) => {
// 这里给你的位置赋值
this.markers[1].latitude = res.latitude;
this.markers[1].longitude = res.longitude;
this.currentLatitude = res.latitude;
this.currentLongitude = res.longitude;
},
fail: function() {
console.log('fail')
},
complete: () => {
// 默认调用开车方式
this.goTo('car')
}
})
- 绘制路线相关代码
drawPolyline(self,color){
return {
origin: this.longitude + ',' + this.latitude,
destination: this.currentLongitude +',' +this.currentLatitude,
success(data) {
var points = [];
if (data.paths && data.paths[0] && data.paths[0].steps) {
var steps = data.paths[0].steps;
for (var i = 0; i < steps.length; i++) {
var poLen = steps[i].polyline.split(';');
for (var j = 0; j < poLen.length; j++) {
points.push({
longitude: parseFloat(poLen[j].split(',')[0]),
latitude: parseFloat(poLen[j].split(',')[1])
})
}
}
}
self.distance= data.paths[0].distance;
if(data.paths[0].distance / 1000 > 50) {
self.maxDuration = true;
} else {
self.maxDuration = false;
}
self.duration= parseInt(data.paths[0].duration/60),
self.polyline= [{
points: points,
color: color,
width: 6,
arrowLine: true
}]
},
fail(e) {
console.log(e)
},
complete() {
console.log('complate')
}
}
},
getPolyline(_type){
var amap = new amapFile.AMapWX({ key: this.key });
var self = this;
switch (_type){
case 'car':
amap.getDrivingRoute(this.drawPolyline(this,"#0091ff"));
break;
case 'walk':
if(this.maxDuration) {
return false;
}
amap.getWalkingRoute(this.drawPolyline(this, "#1afa29"));
break;
case 'ride':
if(this.maxDuration) {
return false;
}
amap.getRidingRoute(this.drawPolyline(this, "#1296db"));
break;
default:
return false;
}
},
- 最后点击切换方式时调用方法
goTo(_type){
this.getPolyline(_type);
this.active = _type;
}
我是海明月,前端小学生。
我的千日蜕变计划正式启动,希望您能够监督我执行。谢谢。
如果有不对的地方,也希望大佬指正。
完整代码如下
<template>
<view>
<!-- <page-head :title="title"></page-head> -->
<view class="uni-common-mt">
<view>
<view class="map-wrapper">
<map :latitude="latitude" scale="12" :longitude="longitude" :markers="markers" :polyline="polyline" ></map>
<view class="info-wrapper">
<view class="selectType">
<view @click="goTo('car')" class="type" :class="active === 'car' ? 'active' : ''">驾车</view>
<view @click="goTo('walk')" class="type" :class="active === 'walk' ? 'active' : ''">步行</view>
<view @click="goTo('ride')" class="type" :class="active === 'ride' ? 'active' : ''">骑行</view>
</view>
<view class="navigatePic" @click="handleNavigate">导航</view>
<view v-if="maxDuration && active!=='car'" class="info">
<text>距离太远,请选择合适的方式前往</text>
</view>
<view v-else class="info">
<text>{{duration | formatTime}}小时</text>
<text>{{distance | filterDistance}}公里</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import amapFile from './amap-wx.js';
export default {
data() {
return {
title: 'map',
// latitude: 31.886143, // 万达的位置
// longitude: 117.344212, // 万达管家的位置
latitude: 28.193688, // 白白管家的位置
longitude: 113.010925, // 白白管家的位置
key: 'c290b7e016c85e8f279b2f80018c6fbf',
distance: 0,
duration: 0,
maxDuration: false,
curentLatitude: '',
curentLongitude: '',
active: 'car',
polyline: null,
markers: [{
latitude: 28.193688,
longitude: 113.010925,
// iconPath: '../../static/location@3x.png',
title:'白白管家',
label:{
content:'白白管家',
color:'#F76350',
bgColor:'#fff',
padding:5,
borderRadius:4
},
callout:{
content:'白白管家',
color:'#F76350',
fontSize:12
}
}, {
latitude: 28.188597,
longitude: 113.006853,
// iconPath: '../../static/location@3x.png',
title:'您的位置',
label:{
content:'您的位置',
color:'#F76350',
bgColor:'#fff',
padding:5,
borderRadius:4
},
callout:{
content:'您的位置',
color:'#F76350',
fontSize:12
}
}]
}
},
onLoad() {
console.log('amapFile', amapFile)
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.markers[1].latitude = res.latitude;
this.markers[1].longitude = res.longitude;
this.currentLatitude = res.latitude;
this.currentLongitude = res.longitude;
},
fail: function() {
console.log('fail')
},
complete: () => {
this.goTo('car')
}
})
},
methods: {
handleNavigate() {
uni.openLocation({
latitude: this.latitude,
longitude: this.longitude,
name: '白白管家',
address: '长沙火车站对面',
success: function () {
console.log('success');
}
});
},
drawPolyline(self,color){
return {
origin: this.longitude + ',' + this.latitude,
destination: this.currentLongitude +',' +this.currentLatitude,
success(data) {
var points = [];
if (data.paths && data.paths[0] && data.paths[0].steps) {
var steps = data.paths[0].steps;
for (var i = 0; i < steps.length; i++) {
var poLen = steps[i].polyline.split(';');
for (var j = 0; j < poLen.length; j++) {
points.push({
longitude: parseFloat(poLen[j].split(',')[0]),
latitude: parseFloat(poLen[j].split(',')[1])
})
}
}
}
self.distance= data.paths[0].distance;
console.log(data.paths[0].distance / 1000 > 50)
console.log(self.active !== 'car')
if(data.paths[0].distance / 1000 > 50) {
self.maxDuration = true;
} else {
self.maxDuration = false;
}
self.duration= parseInt(data.paths[0].duration/60),
self.polyline= [{
points: points,
color: color,
width: 6,
arrowLine: true
}]
},
fail(e) {
console.log(e)
},
complete() {
console.log('complate')
}
}
},
getPolyline(_type){
var amap = new amapFile.AMapWX({ key: this.key });
var self = this;
switch (_type){
case 'car':
amap.getDrivingRoute(this.drawPolyline(this,"#0091ff"));
break;
case 'walk':
if(this.maxDuration) {
return false;
}
amap.getWalkingRoute(this.drawPolyline(this, "#1afa29"));
break;
case 'ride':
if(this.maxDuration) {
return false;
}
amap.getRidingRoute(this.drawPolyline(this, "#1296db"));
break;
default:
return false;
}
},
goTo(_type){
this.getPolyline(_type);
this.active = _type;
}
},
filters: {
filterDistance(val) {
return (val/1000).toFixed(2)
},
formatTime(val) {
return (val/60).toFixed(2)
}
}
}
</script>
<style>
.map-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 150upx;
width: 100%;
}
.map-wrapper map {
width: 100%;
height: 100%;
}
.info-wrapper{
background: #fff;
height: 150upx;
display: flex;
flex-direction: column;
}
.selectType {
position: relative;
display: flex;
}
.selectType view {
flex: 1;
height: 60upx;
line-height: 60upx;
text-align: center;
}
.type {
border-bottom: 1px solid #ccc;
}
.type:last-child {
border-right: none;
}
.type.active {
color: #10D5AF;
border-color: #10D5AF;
}
.navigatePic {
position: absolute;
right: 10upx;
background: #10D4AF;
width: 100upx;
height: 100upx;
border-radius: 50%;
bottom:40upx;
text-align:center;
line-height:100upx;
color:#fff;
font-weight:bold;
}
.info {
display: flex;
flex-direction: row;
line-height: 80upx;
font-size:32upx;
font-weight:bold;
padding:20upx;
}
.info text {
margin-right: 40upx;
}
</style>