视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue+高德地图写地图选址组件的方法
2020-11-27 21:56:41 责编:小采
文档


前言

现在做这个移动端的项目中有一个地图选址的功能,本来高德地图中有一个现成的选址组件,但是有两个问题,因为他是用iframe引用的,第一改不了样式,这点还勉强能接受;第二他的左上角有一个返回键,在搜索的时候可以返回到地图界面,但是在地图界面时点返回没有用,试了半天也没搞明白怎么监听到那个返回键的点击事件,所以趁这两天项目基本结束自己写一个把这个功能优化一下,也方便以后使用。

开整

vue的安装使用啥的我在这就不说了,直接开始地图选址组件。
首先上高德开放平台弄一个key,然后在index.html引入

<script src="https://webapi.amap.com/maps?v=1.4.14&key=yourKey"></script>

然后写样式

css我就不贴了,大概就是上面一个搜索框,中间是地图,然后下面是一个地址列表,然后一个搜索结果的列表。有一点值得注意一下,就是地图中心的定位图标,这个自己弄一个定位图标使用绝对定位,上下左右外边距为auto的方法定位到中间,但是这时地图的中心点是在图标的中心,我们的图标不是一般都是下面是尖的嘛,选址的时候都会用尖的部分指到目标位置,那这样就会有一点偏差,怎么办呢,比如我们的图标是30*30的,我们就把bottom的值设为图标的高度的一半15,或者是把top设为-15,就ok了,另外注意在切图的时候靠着图标边切,不要留空白。
data里定义的值:

data(){
 return{
 center: [106.532357,29.57212],//纬度-经度
 search_key: '', //搜索值
 lists: [],	//地点列表
 search_list: [], //搜索结果列表
 noSearchShow: false //无搜索结果提示,无搜索结果时会显示暂无搜索结果
 }
 },

然后在mounted中调取第一个方法------初始化地图:

adMap(){
	//初始化地图
 var map = new AMap.Map('container',{
 zoom: 14, //缩放级别
 center: this.center, //设置地图中心点
 //resizeEnable: true, //地图初始化加载定位到当前城市
 });
 //获取初始中心点并赋值
 var currentCenter = map.getCenter();//此方法是获取当前地图的中心点
 this.center = [currentCenter.lng,currentCenter.lat];//将获取到的中心点的纬度经度赋值给data的center
 //根据地图中心点查附近地点,此方法在下方
 this.centerSearch();
 //监听地图移动事件,并在移动结束后获取地图中心点并更新地点列表
 var moveendFun = (e) => {
 // 获取地图中心点
 currentCenter = map.getCenter();
 this.center = [currentCenter.lng,currentCenter.lat]
 //根据地图中心点查附近地点
 this.centerSearch();
 }
 // 绑定事件移动地图事件
 map.on('moveend', moveendFun);
},

根据中心点查询附近地点

centerSearch(){
 AMap.service(["AMap.PlaceSearch"], () => {
 //构造地点查询类
 var placeSearch = new AMap.PlaceSearch({ 
 type: '汽车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|地名地址信息', // 兴趣点类别
 pageSize: 30, // 单页显示结果条数
 pageIndex: 1, // 页码
 city: "全国", // 兴趣点城市
 autoFitView: false // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
 });
 //根据地图中心点查附近地点
 placeSearch.searchNearBy('', [this.center[0],this.center[1]], 200, (status, result) => {
 if(status == 'complete'){
 this.lists = result.poiList.pois//将查询到的地点赋值
 }
 });
 });
 },

这个方法没什么好说的,就是高德地图的方法,copy过来就行了,要注意的几个点:

1.type,需要查找的地点的分类,这个可以按需添加减少;

2.这里可以传条数和页码,如果需要做上拉加载的都可以使用这个;

3.placeSearch.searchNearBy(),这个方法的第二个参数就是经纬度,是一个数组,这里要注意纬度在前,经度在后;

4.然后是返回值status是状态,result是结果,具体的请参考:
https://lbs.amap.com/api/javascript-api/reference/search#m_AMap.PlaceSearch

到这里我们一个地点展示的功能就可以使用了,接下来就是搜索
首先我使用了watch监听了用户输入的搜索值,当search_key(用户输入的值)不为空时:

<!--搜索列表-->
<div class="search-list" v-if="!!search_key">
 <ul>
 <li v-for="(item, index) in search_list" :key="index" @click="onSearchLi(item.location)">
 <span>{{item.name}}</span>
 <p>{{item.address}}</p>
 </li>
 <li v-if="noSearchShow"><p>暂无搜索结果</p></li>
 </ul>
</div>

我们使用v-if判断当search_key不为空时就显示搜索列表,这里的双感叹号就是强制转换为布尔值,不写也可以的,具体为啥我在这就不多说了;这里的search-list就是定位在页面上的,把地图给它覆盖了,css相信大家都会。

然后我们来看一看搜索的方法:

keySearch(){
 AMap.service(["AMap.PlaceSearch"], () => {
 //构造地点查询类
 var placeSearch = new AMap.PlaceSearch({
 type: '汽车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|地名地址信息', // 兴趣点类别
 pageSize: 30, // 单页显示结果条数
 pageIndex: 1, // 页码
 city: "全国", // 兴趣点城市
 citylimit: false, //是否强制在设置的城市内搜索
 autoFitView: false // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
 });
 //关键字查询
 placeSearch.search(this.search_key,(status, result) => {
 if(status == 'complete'){
 if(result.poiList.count === 0){
 this.noSearchShow = true;
 }else{
 this.search_list = result.poiList.pois//将查询到的地点赋值
 this.noSearchShow = false;
 }
 }else{
 this.search_list = [];
 this.noSearchShow = true;
 }
 });
 });
 },

还是copy高德的方法过来,然后进行配置,主要说一下这里返回结果的处理:
1.status为complete的时候是完成查询,其中完成后有一个count 参数是代表查到的总条数,如果总条数为0时,我们就this.noSearchShow = true,这个我们上面说了,当noSearchShow 为true的时候会显示‘暂无搜索结果';如果count不为0的时候,也就是else中的内容,那就将我们查询到的值赋给this.search_list,然后遍历出来,然后记得this.noSearchShow = false;
2.另外我是将status不为complete的情况统统视为没有搜索结果,这时候我们就清空this.search_list,然后this.noSearchShow = true。

这时候搜索也完成了,接下来如果我们不想搜索了,清空了搜索框,这是点×的清空方法:

<span class="clear" v-if="search_key" @click="search_key = ''"></span>

直接@click="search_key = ‘'"就行了,当然我们也可以用输入键盘退格删除,这时要注意清空input之后我们要把search_list也清空并且this.noSearchShow = false,这里我是使用了watch来监控search_key:

watch: {
 search_key(newv,oldv){
 if(newv == ''){
 this.search_list = [];
 this.noSearchShow = false;
 }
 }
 },

至于为什么要清空呢?因为如果我们第一次进行了搜索,这时search_list就有值了,如果下次在进入搜索状态,就会直接显示上次的搜索列表,所以我们要清空一下。

上面是说的放弃了搜索,这里是说如果搜索到了我们想要的结果,那我们会去点击我们想要的结果:

//这里我们遍历search_list的时候将location传进来
onSearchLi(location){
 this.center = [location.lng,location.lat];
 this.adMap();
 this.search_key = '';
},

这里的步骤是:
1.先给this.center赋值,这里注意纬度在前,经度在后!
2.调取上面的this.adMap()查询一次新的lists;
3.清空search_key,清空search_key后搜索列表就会自动隐藏了,另外因为我们用watch监控了search_key ,所以在这里清空search_key 的同时也会清空search_list并将noSearchShow设为false。

这里基本上就差不多完成了,还有就是最后一步,我们点击地址列表的时候获取地址信息:

//html
<li v-for="(item, index) in lists" :key="index" @click="onResLi(item)">
 <span>{{item.name}}</span>
 <p>{{item.address}}</p>
</li>

//js 
onResLi(e){
 console.log(e)
}

这里e打印出来就是选择的地点信息。
在这里我们组件就完成了,另外可能还需要一个回到当前位置的方法,我说下思路,就不在写出来了:
1.在地图上写一个图标,给一个点击事件;
2.点击的时候使用高德的定位方法获取当前位置的坐标,然后赋值给this.center;
3.再调一次adMap()方法就会回到当前位置了。

欢迎大佬批评指正优化,小弟献丑了~

以上所述是小编给大家介绍的vue+高德地图写地图选址组件的方法详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

下载本文
显示全文
专题