效果图如下:
主要功能:搜索,分页,距离显示,选择地址,移动地图查询附近相关地点。
1.首先在index.html引入高德地图的js;
<!-- 高德地图的引用 -->
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你的key">
</script>
<!--引入UI组件库(1.0版本) -->
<script src="//webapi.amap.com/ui/1.0/main.js"></script>
2.在vue项目中配置AMap,AMapUI,在项目配置里面加上如下代码:
//方式一
externals: {
'AMap': 'AMap',
'AMapUI': 'AMapUI'
},
//方式二
configureWebpack: {
externals: {
AMap: "window.AMap",
AMapUI: "window.AMapUI"
}
},
(1)如果是用webpack自行定义配置的;
(2)如果用的是vue-cli3脚手架配置的:
3.开始写代码了,html部分如下:
<van-popup
class="address-map-wrap"
v-model="value"
position="right"
:style="{ width: '100%', height: '100%' }"
:overlay="false"
@open="onOpenMap"
>
<div class="mymapM">
<!--loading-->
<div v-if="loading" class="loading">
<van-loading type="spinner" />
</div>
<div class="current-location" @click="goBackOrign()">
<van-icon name="aim" />
</div>
<div class="header">
<dt-header
:title="header.title"
:left-text="header.leftText"
:right-text="header.rightText"
:left-arrow="header.leftArrow"
@click-left="onClickLeft"
@click-right="onConfirmChoose"
/>
</div>
<div class="con-map">
<!--地图-->
<div class="mapbox">
<div class="map" id="container"></div>
<div class="sign"></div>
</div>
</div>
<div class="con-box">
<!-- 搜索 -->
<van-search
v-model="search_key"
:show-action="showCancelBtn"
placeholder="请输入搜索关键词"
@input="keyInputSearch"
@cancel="onCancel"
/>
<!--地址列表-->
<div class="Hlist-box">
<van-list
v-model="loadingList"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
:offset="200"
:immediate-check="false"
>
<ul class="van-clearfix">
<li
v-for="(item, index) in lists"
:key="index"
@click="onAddressLi(item)"
>
<div>
<span>{{ item.name }}</span>
<p>{{ item.distance }}-{{ item.address }}</p>
</div>
<b v-if="item.isChecked">
<van-icon color="#04BE02" name="success" />
</b>
</li>
</ul>
</van-list>
</div>
</div>
</div>
</van-popup>
4.样式如下,用的是less:
.mymapM {
.header {
position: fixed;
z-index: 99999;
width: 100%;
}
.con-map {
height: 300px;
width: 100%;
.mapbox {
position: fixed;
z-index: 111;
width: 100%;
height: 300px;
.map {
width: 100%;
height: 300px;
}
}
}
.con-box {
height: calc(~"100vh - @{mapHeight}");
max-height: calc(~"100vh - @{mapHeight}");
overflow-y: auto;
.van-search {
position: fixed;
width: 100%;
}
.Hlist-box {
width: 100%;
padding: 60px 0 10px 0;
background: #fff;
border-radius: 5px;
li {
padding: 10px 15px;
border-bottom: 1px solid #eee;
display: flex;
b {
display: inline-block;
i {
margin: 10px 10px 0 0;
}
}
div {
width: 100%;
}
span {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 14px;
display: inline-block;
width: 90%;
}
p {
margin-top: 0px;
color: #a6a6a6;
// white-space: nowrap;
// text-overflow: ellipsis;
// overflow: hidden;
font-size: 12px;
width: 90%;
}
}
}
}
}
.no-search-content {
text-align: center;
p {
font-size: 12px;
padding-bottom: 10px;
}
}
.current-location {
position: fixed;
z-index: 100000;
top: 250px;
right: 10px;
font-size: 25px;
background: #fff;
border-radius: 100px;
height: 40px;
width: 40px;
line-height: 45px;
text-align: center;
}
.loading {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 99999999;
// width: 100%;
// height: 100%;
// background-color: rgba(0, 0, 0, 0.3);
.van-loading {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 99999999;
color: green;
}
}
5.方法代码如下:
<script>
import {
Search,
Popup,
Icon,
Loading,
List,
} from "vant";
import AMap from "AMap";
import AMapUI from "AMapUI";
import dtHeader from "@/components/dtHeader";
import { dtBack, dtLocationInfo, getDevice } from "@/config/bridging";
export default {
name: "mapAddress",
components: {
[Loading.name]: Loading,
[Search.name]: Search,
[dtHeader.name]: dtHeader,
[Popup.name]: Popup,
[Icon.name]: Icon,
[List.name]: List,
},
props: {
value: Boolean,
currentLocation: Array,
currentAdCode: String, //当前定位所在的AdCode北京
},
data() {
return {
header: {
title: "调查地点",
leftText: "",
rightText: "确定",
leftArrow: true,
},
loadingList: false,
finished: false,
pageNearNum: 1,
pageKeyNum: 1,
originCenter: [116.396574, 39.992706], //初始的地址
center: [116.396574, 39.992706], //默认的 经度+纬度北京
search_key: "", //搜索值
lists: [], //地点列表
marker: "",
map: "",
loading: false,
checkedAddress: "", //选中的地址
showCancelBtn: false, //取消按钮的显示问题
};
},
watch: {
search_key(newv, oldv) {
if (newv == "") {
this.lists = [];
this.showCancelBtn = false;
this.adMap();
}
},
},
created() {},
mounted() {},
methods: {
onClickLeft() {
this.$emit("onClickLeft", false);
},
onConfirmChoose() {
if (this.checkedAddress) {
this.$emit("onClickLeft", false);
this.$emit("onChooseAddress", this.checkedAddress);
} else {
this.$toast.fail("请先选择地址");
return;
}
},
//用的popup弹框
onOpenMap() {
this.$nextTick(() => {
this.lists = [];
this.checkedAddress = "";
this.pageNearNum = 1;
this.pageKeyNum = 1;
this.getCurrentLocation(); //获取当前位置,app内使用原生获取当前定位
});
},
//分页加载
onLoad() {
if (this.search_key) {
this.loadingList = true;
this.keySearch(++this.pageKeyNum);
} else {
this.loadingList = true;
this.centerSearch(++this.pageNearNum);
}
},
//初次选择位置的时候,获取当前地址的经纬度
getCurrentLocation() {
if (this.currentLocation.length > 0 && this.currentAdCode) {
this.center = this.currentLocation; // 当前定位
this.originCenter = this.currentLocation; //保存最原始的位置
this.adMap(); //初始化地图
} else {
dtLocationInfo((res, a, b) => {
console.log("返回的地址信息:", res, a, b);
var device = getDevice();
if (device == "android") {
var data = JSON.parse(res);
this.center = [data.longitude, data.latitude];
this.originCenter = [data.longitude, data.latitude];
this.currentAdCode = data.adCode;
} else if (device == "ios" || device == "iPhoneX") {
if (res) {
this.center = [a.longitude, a.latitude];
this.originCenter = [a.longitude, a.latitude];
this.currentAdCode = a.adCode;
} else {
this.$toast.fail(b);
}
} else {
throw new Error("can't know device type!");
}
this.adMap(); //初始化地图
});
}
},
//创建地图
adMap() {
this.loading = true;
var map = new AMap.Map("container", {
zoom: 13, //缩放级别
center: this.center, //设置地图中心点
resizeEnable: true,
});
var currentCenter = map.getCenter(); //此方法是获取当前地图的中心点
this.center = [currentCenter.lng, currentCenter.lat]; //将获取到的中心点的纬度经度赋值给data的center
this.map = map;
//创建当前标志;
var currentMarker = new AMap.CircleMarker({
map: map,
center: this.originCenter, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
radius: 8,
strokeColor: "white",
strokeWeight: 2,
strokeOpacity: 1,
fillColor: "#4c95fb",
fillOpacity: 1,
zIndex: 10,
bubble: true,
cursor: "pointer",
});
//创建位置标记
this.marker = new AMap.Marker({
map: map,
position: new AMap.LngLat(currentCenter.lng, currentCenter.lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
});
if (this.search_key) {
this.lists = [];
this.keySearch(1); //根据关键字搜索
} else {
this.lists = [];
this.centerSearch(1); //根据地图中心点查附近地点,此方法在下方
}
//监听地图移动事件,并在移动结束后获取地图中心点并更新地点列表
var moveendFun = (e) => {
//没有关键字的时候,移动地图,数据及时刷新,更新地图,否则中心点不变
if (!this.search_key) {
currentCenter = map.getCenter(); // 获取地图中心点
this.center = [currentCenter.lng, currentCenter.lat];
this.marker.setPosition([currentCenter.lng, currentCenter.lat]); //更新标记的位置
}
};
//更新数据
var centerSearch = () => {
if (!this.search_key) {
this.loading = true;
this.checkedAddress = "";
this.lists = [];
this.centerSearch(1);
}
};
// 绑定事件移动地图事件
map.on("touchmove", moveendFun); //触摸移动进行中时触发事件,仅适用移动设备
map.on("touchend", centerSearch); //触摸结束时触发事件,仅适用移动设备,更新数据
},
//根据地图中心点查附近地
centerSearch(pageNum) {
AMap.service(["AMap.PlaceSearch"], () => {
//构造地点查询类
var placeSearch = new AMap.PlaceSearch({
type:
"汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息", // 兴趣点类别
pageSize: 20, // 单页显示结果条数
pageIndex: parseInt(pageNum), // 页码
city: "全国", // 兴趣点城市
extensions: "all",
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
var geometryUtil = AMap.GeometryUtil;
//根据地图中心点查附近地点
placeSearch.searchNearBy(
this.search_key,
[this.center[0], this.center[1]],
10000,
(status, result) => {
if (status == "complete") {
console.log("searchNearBy--complete---:", result);
this.lists = this.lists.concat(result.poiList.pois);
this.lists.length < result.poiList.count
? (this.finished = false)
: (this.finished = true);
this.lists = this.lists.map((item) => {
let distance = geometryUtil.distance(this.originCenter, [
item.location.lng,
item.location.lat,
]);
item.distance =
parseInt(distance) > 1000
? parseFloat(distance / 1000).toFixed(2) + "km"
: parseInt(distance) + "m";
return item;
});
this.lists[0].isChecked = true;
this.checkedAddress = this.lists[0];
this.loading = false;
this.loadingList = false;
} else {
console.log("searchNearBy-notcomplete------:", result);
// this.loadingList = false;
this.finished = true;
this.loading = false;
}
}
);
});
},
keyInputSearch() {
this.lists = [];
this.keySearch(1);
},
//关键字搜索
keySearch(pageNum) {
this.loading = true;
this.showCancelBtn = true;
if (this.search_key) {
AMap.service(["AMap.PlaceSearch"], () => {
//构造地点查询类
var placeSearch = new AMap.PlaceSearch({
type:
"汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施", // 兴趣点类别
pageSize: 20, // 单页显示结果条数
pageIndex: pageNum, // 页码
city: this.currentAdCode, // 兴趣点城市,默认北京
extensions: "all",
citylimit: false, //是否强制限制在设置的城市内搜索
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
var geometryUtil = AMap.GeometryUtil;
//关键字查询
placeSearch.search(this.search_key, (status, result) => {
if (status == "complete") {
console.log("search:", result);
if (result.poiList.count === 0) {
this.loading = false;
this.finished = true;
} else {
this.lists = this.lists.concat(result.poiList.pois);
this.lists.length < result.poiList.count
? (this.finished = false)
: (this.finished = true);
this.lists = this.lists.map((item) => {
if (
item.location.lng == this.currentLocation[0] &&
item.location.lat == this.currentLocation[1]
) {
item.isChecked = true;
this.checkedAddress = item;
} else {
item.isChecked = false;
}
let distance = geometryUtil.distance(this.originCenter, [
item.location.lng,
item.location.lat,
]);
item.distance =
parseInt(distance) > 1000
? parseFloat(distance / 1000).toFixed(2) + "km"
: parseInt(distance) + "m";
return item;
});
this.loading = false;
this.loadingList = false;
}
} else {
// this.lists = [];
this.loading = false;
this.finished = true;
}
});
});
}
},
onAddressLi(e) {
this.checkedAddress = e;
this.map.setCenter([e.location.lng, e.location.lat]); //更新地图中心
this.marker.setPosition([e.location.lng, e.location.lat]); //更新标记的位置
this.lists = this.lists.map((item) => {
if (item.id == e.id) {
item.isChecked = true;
} else {
item.isChecked = false;
}
return item;
});
},
onCancel() {
this.search_key = "";
this.checkedAddress = "";
this.pageNearNum = 1;
this.pageKeyNum = 1;
this.map.setCenter(this.originCenter);
this.marker.setPosition(this.originCenter); //更新标记的位置
},
//回到当前位置
goBackOrign() {
this.map.setCenter(this.originCenter);
},
},
};
</script>